1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_session_pool_test_base.h"
6
7 #include <sys/types.h>
8
9 #include <memory>
10 #include <ostream>
11 #include <set>
12 #include <string>
13 #include <utility>
14
15 #include "base/functional/bind.h"
16 #include "base/functional/callback.h"
17 #include "base/logging.h"
18 #include "base/run_loop.h"
19 #include "base/strings/string_util.h"
20 #include "base/test/bind.h"
21 #include "base/test/scoped_feature_list.h"
22 #include "base/test/simple_test_tick_clock.h"
23 #include "base/test/test_mock_time_task_runner.h"
24 #include "base/time/time.h"
25 #include "net/base/features.h"
26 #include "net/base/host_port_pair.h"
27 #include "net/base/http_user_agent_settings.h"
28 #include "net/base/load_flags.h"
29 #include "net/base/mock_network_change_notifier.h"
30 #include "net/base/net_error_details.h"
31 #include "net/base/net_errors.h"
32 #include "net/base/network_anonymization_key.h"
33 #include "net/base/privacy_mode.h"
34 #include "net/base/proxy_chain.h"
35 #include "net/base/proxy_server.h"
36 #include "net/base/schemeful_site.h"
37 #include "net/base/session_usage.h"
38 #include "net/base/test_proxy_delegate.h"
39 #include "net/cert/mock_cert_verifier.h"
40 #include "net/dns/mock_host_resolver.h"
41 #include "net/dns/public/dns_query_type.h"
42 #include "net/dns/public/host_resolver_source.h"
43 #include "net/dns/public/secure_dns_policy.h"
44 #include "net/http/http_response_headers.h"
45 #include "net/http/http_response_info.h"
46 #include "net/http/http_server_properties.h"
47 #include "net/http/http_util.h"
48 #include "net/http/transport_security_state.h"
49 #include "net/http/transport_security_state_test_util.h"
50 #include "net/quic/address_utils.h"
51 #include "net/quic/crypto/proof_verifier_chromium.h"
52 #include "net/quic/mock_crypto_client_stream_factory.h"
53 #include "net/quic/mock_quic_context.h"
54 #include "net/quic/mock_quic_data.h"
55 #include "net/quic/properties_based_quic_server_info.h"
56 #include "net/quic/quic_chromium_alarm_factory.h"
57 #include "net/quic/quic_chromium_client_session.h"
58 #include "net/quic/quic_chromium_client_session_peer.h"
59 #include "net/quic/quic_context.h"
60 #include "net/quic/quic_http_stream.h"
61 #include "net/quic/quic_http_utils.h"
62 #include "net/quic/quic_server_info.h"
63 #include "net/quic/quic_session_key.h"
64 #include "net/quic/quic_session_pool_peer.h"
65 #include "net/quic/quic_test_packet_maker.h"
66 #include "net/quic/quic_test_packet_printer.h"
67 #include "net/quic/test_task_runner.h"
68 #include "net/socket/next_proto.h"
69 #include "net/socket/socket_tag.h"
70 #include "net/socket/socket_test_util.h"
71 #include "net/spdy/spdy_session_test_util.h"
72 #include "net/spdy/spdy_test_util_common.h"
73 #include "net/ssl/test_ssl_config_service.h"
74 #include "net/test/cert_test_util.h"
75 #include "net/test/gtest_util.h"
76 #include "net/test/test_data_directory.h"
77 #include "net/test/test_with_task_environment.h"
78 #include "net/third_party/quiche/src/quiche/common/http/http_header_block.h"
79 #include "net/third_party/quiche/src/quiche/common/quiche_data_writer.h"
80 #include "net/third_party/quiche/src/quiche/http2/test_tools/spdy_test_utils.h"
81 #include "net/third_party/quiche/src/quiche/quic/core/crypto/crypto_handshake.h"
82 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_crypto_client_config.h"
83 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_decrypter.h"
84 #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_encrypter.h"
85 #include "net/third_party/quiche/src/quiche/quic/core/quic_constants.h"
86 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
87 #include "net/third_party/quiche/src/quiche/quic/platform/api/quic_test.h"
88 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_clock.h"
89 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
90 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_config_peer.h"
91 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_connection_peer.h"
92 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_path_validator_peer.h"
93 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_session_peer.h"
94 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_spdy_session_peer.h"
95 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
96 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
97 #include "net/url_request/static_http_user_agent_settings.h"
98 #include "testing/gmock/include/gmock/gmock.h"
99 #include "testing/gtest/include/gtest/gtest.h"
100 #include "url/gurl.h"
101 #include "url/scheme_host_port.h"
102 #include "url/url_constants.h"
103
104 using std::string;
105
106 namespace net::test {
107
RequestBuilder(QuicSessionPoolTestBase * test,QuicSessionPool * pool)108 QuicSessionPoolTestBase::RequestBuilder::RequestBuilder(
109 QuicSessionPoolTestBase* test,
110 QuicSessionPool* pool)
111 : quic_version(test->version_),
112 net_log(test->net_log_),
113 failed_on_default_network_callback(
114 test->failed_on_default_network_callback_),
115 callback(test->callback_.callback()),
116 request(pool) {}
RequestBuilder(QuicSessionPoolTestBase * test)117 QuicSessionPoolTestBase::RequestBuilder::RequestBuilder(
118 QuicSessionPoolTestBase* test)
119 : RequestBuilder(test, test->factory_.get()) {}
120 QuicSessionPoolTestBase::RequestBuilder::~RequestBuilder() = default;
121
CallRequest()122 int QuicSessionPoolTestBase::RequestBuilder::CallRequest() {
123 return request.Request(
124 std::move(destination), quic_version, proxy_chain,
125 std::move(proxy_annotation_tag), http_user_agent_settings, session_usage,
126 privacy_mode, priority, socket_tag, network_anonymization_key,
127 secure_dns_policy, require_dns_https_alpn, cert_verify_flags, url,
128 net_log, &net_error_details,
129 MultiplexedSessionCreationInitiator::kUnknown,
130 std::move(failed_on_default_network_callback), std::move(callback));
131 }
QuicSessionPoolTestBase(quic::ParsedQuicVersion version,std::vector<base::test::FeatureRef> enabled_features,std::vector<base::test::FeatureRef> disabled_features)132 QuicSessionPoolTestBase::QuicSessionPoolTestBase(
133 quic::ParsedQuicVersion version,
134 std::vector<base::test::FeatureRef> enabled_features,
135 std::vector<base::test::FeatureRef> disabled_features)
136 : host_resolver_(std::make_unique<MockHostResolver>(
137 /*default_result=*/MockHostResolverBase::RuleResolver::
138 GetLocalhostResult())),
139 socket_factory_(std::make_unique<MockClientSocketFactory>()),
140 version_(version),
141 client_maker_(version_,
142 quic::QuicUtils::CreateRandomConnectionId(
143 context_.random_generator()),
144 context_.clock(),
145 kDefaultServerHostName,
146 quic::Perspective::IS_CLIENT,
147 /*client_priority_uses_incremental=*/true,
148 /*use_priority_header=*/true),
149 server_maker_(version_,
150 quic::QuicUtils::CreateRandomConnectionId(
151 context_.random_generator()),
152 context_.clock(),
153 kDefaultServerHostName,
154 quic::Perspective::IS_SERVER,
155 /*client_priority_uses_incremental=*/false,
156 /*use_priority_header=*/false),
157 http_server_properties_(std::make_unique<HttpServerProperties>()),
158 cert_verifier_(std::make_unique<MockCertVerifier>()),
159 net_log_(NetLogWithSource::Make(NetLog::Get(),
160 NetLogSourceType::QUIC_SESSION_POOL)),
161 failed_on_default_network_callback_(base::BindRepeating(
162 &QuicSessionPoolTestBase::OnFailedOnDefaultNetwork,
163 base::Unretained(this))),
164 quic_params_(context_.params()) {
165 enabled_features.push_back(features::kAsyncQuicSession);
166 scoped_feature_list_.InitWithFeatures(enabled_features, disabled_features);
167 FLAGS_quic_enable_http3_grease_randomness = false;
168 context_.AdvanceTime(quic::QuicTime::Delta::FromSeconds(1));
169
170 // It's important that different proxies have different IPs, to avoid
171 // pooling them together.
172 host_resolver_->rules()->AddRule(kProxy1HostName, "127.0.1.1");
173 host_resolver_->rules()->AddRule(kProxy2HostName, "127.0.1.2");
174 }
175
176 QuicSessionPoolTestBase::~QuicSessionPoolTestBase() = default;
Initialize()177 void QuicSessionPoolTestBase::Initialize() {
178 DCHECK(!factory_);
179 factory_ = std::make_unique<QuicSessionPool>(
180 net_log_.net_log(), host_resolver_.get(), &ssl_config_service_,
181 socket_factory_.get(), http_server_properties_.get(),
182 cert_verifier_.get(), &transport_security_state_, proxy_delegate_.get(),
183 /*sct_auditing_delegate=*/nullptr,
184 /*SocketPerformanceWatcherFactory*/ nullptr,
185 &crypto_client_stream_factory_, &context_);
186 }
187
MaybeMakeNewConnectionIdAvailableToSession(const quic::QuicConnectionId & new_cid,quic::QuicSession * session,uint64_t sequence_number)188 void QuicSessionPoolTestBase::MaybeMakeNewConnectionIdAvailableToSession(
189 const quic::QuicConnectionId& new_cid,
190 quic::QuicSession* session,
191 uint64_t sequence_number) {
192 quic::QuicNewConnectionIdFrame new_cid_frame;
193 new_cid_frame.connection_id = new_cid;
194 new_cid_frame.sequence_number = sequence_number;
195 new_cid_frame.retire_prior_to = 0u;
196 new_cid_frame.stateless_reset_token =
197 quic::QuicUtils::GenerateStatelessResetToken(new_cid_frame.connection_id);
198 session->connection()->OnNewConnectionIdFrame(new_cid_frame);
199 }
200
CreateStream(QuicSessionRequest * request)201 std::unique_ptr<HttpStream> QuicSessionPoolTestBase::CreateStream(
202 QuicSessionRequest* request) {
203 std::unique_ptr<QuicChromiumClientSession::Handle> session =
204 request->ReleaseSessionHandle();
205 if (!session || !session->IsConnected()) {
206 return nullptr;
207 }
208
209 std::set<std::string> dns_aliases =
210 session->GetDnsAliasesForSessionKey(request->session_key());
211 return std::make_unique<QuicHttpStream>(std::move(session),
212 std::move(dns_aliases));
213 }
214
HasActiveSession(const url::SchemeHostPort & scheme_host_port,PrivacyMode privacy_mode,const NetworkAnonymizationKey & network_anonymization_key,const ProxyChain & proxy_chain,SessionUsage session_usage,bool require_dns_https_alpn)215 bool QuicSessionPoolTestBase::HasActiveSession(
216 const url::SchemeHostPort& scheme_host_port,
217 PrivacyMode privacy_mode,
218 const NetworkAnonymizationKey& network_anonymization_key,
219 const ProxyChain& proxy_chain,
220 SessionUsage session_usage,
221 bool require_dns_https_alpn) {
222 quic::QuicServerId server_id(scheme_host_port.host(),
223 scheme_host_port.port());
224 return QuicSessionPoolPeer::HasActiveSession(
225 factory_.get(), server_id, privacy_mode, network_anonymization_key,
226 proxy_chain, session_usage, require_dns_https_alpn);
227 }
228
HasActiveJob(const url::SchemeHostPort & scheme_host_port,const PrivacyMode privacy_mode,bool require_dns_https_alpn)229 bool QuicSessionPoolTestBase::HasActiveJob(
230 const url::SchemeHostPort& scheme_host_port,
231 const PrivacyMode privacy_mode,
232 bool require_dns_https_alpn) {
233 quic::QuicServerId server_id(scheme_host_port.host(),
234 scheme_host_port.port());
235 return QuicSessionPoolPeer::HasActiveJob(
236 factory_.get(), server_id, privacy_mode, require_dns_https_alpn);
237 }
238
239 // Get the pending, not activated session, if there is only one session alive.
GetPendingSession(const url::SchemeHostPort & scheme_host_port)240 QuicChromiumClientSession* QuicSessionPoolTestBase::GetPendingSession(
241 const url::SchemeHostPort& scheme_host_port) {
242 quic::QuicServerId server_id(scheme_host_port.host(),
243 scheme_host_port.port());
244 return QuicSessionPoolPeer::GetPendingSession(
245 factory_.get(), server_id, PRIVACY_MODE_DISABLED, scheme_host_port);
246 }
247
GetActiveSession(const url::SchemeHostPort & scheme_host_port,PrivacyMode privacy_mode,const NetworkAnonymizationKey & network_anonymization_key,const ProxyChain & proxy_chain,SessionUsage session_usage,bool require_dns_https_alpn)248 QuicChromiumClientSession* QuicSessionPoolTestBase::GetActiveSession(
249 const url::SchemeHostPort& scheme_host_port,
250 PrivacyMode privacy_mode,
251 const NetworkAnonymizationKey& network_anonymization_key,
252 const ProxyChain& proxy_chain,
253 SessionUsage session_usage,
254 bool require_dns_https_alpn) {
255 quic::QuicServerId server_id(scheme_host_port.host(),
256 scheme_host_port.port());
257 return QuicSessionPoolPeer::GetActiveSession(
258 factory_.get(), server_id, privacy_mode, network_anonymization_key,
259 proxy_chain, session_usage, require_dns_https_alpn);
260 }
261
GetSourcePortForNewSessionAndGoAway(const url::SchemeHostPort & destination)262 int QuicSessionPoolTestBase::GetSourcePortForNewSessionAndGoAway(
263 const url::SchemeHostPort& destination) {
264 return GetSourcePortForNewSessionInner(destination, true);
265 }
266
GetSourcePortForNewSessionInner(const url::SchemeHostPort & destination,bool goaway_received)267 int QuicSessionPoolTestBase::GetSourcePortForNewSessionInner(
268 const url::SchemeHostPort& destination,
269 bool goaway_received) {
270 // Should only be called if there is no active session for this destination.
271 EXPECT_FALSE(HasActiveSession(destination));
272 size_t socket_count = socket_factory_->udp_client_socket_ports().size();
273
274 MockQuicData socket_data(version_);
275 socket_data.AddReadPauseForever();
276 socket_data.AddWrite(SYNCHRONOUS, ConstructInitialSettingsPacket());
277 socket_data.AddSocketDataToFactory(socket_factory_.get());
278
279 GURL url("https://" + destination.host() + "/");
280 RequestBuilder builder(this);
281 builder.destination = destination;
282 builder.url = url;
283
284 EXPECT_THAT(callback_.WaitForResult(), IsOk());
285 std::unique_ptr<HttpStream> stream = CreateStream(&builder.request);
286 EXPECT_TRUE(stream.get());
287 stream.reset();
288
289 QuicChromiumClientSession* session = GetActiveSession(destination);
290
291 if (socket_count + 1 != socket_factory_->udp_client_socket_ports().size()) {
292 ADD_FAILURE();
293 return 0;
294 }
295
296 if (goaway_received) {
297 quic::QuicGoAwayFrame goaway(quic::kInvalidControlFrameId,
298 quic::QUIC_NO_ERROR, 1, "");
299 session->connection()->OnGoAwayFrame(goaway);
300 }
301
302 factory_->OnSessionClosed(session);
303 EXPECT_FALSE(HasActiveSession(destination));
304 socket_data.ExpectAllReadDataConsumed();
305 socket_data.ExpectAllWriteDataConsumed();
306 return socket_factory_->udp_client_socket_ports()[socket_count];
307 }
308
309 ProofVerifyDetailsChromium
DefaultProofVerifyDetails()310 QuicSessionPoolTestBase::DefaultProofVerifyDetails() {
311 // Load a certificate that is valid for *.example.org
312 scoped_refptr<X509Certificate> test_cert(
313 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
314 EXPECT_TRUE(test_cert.get());
315 ProofVerifyDetailsChromium verify_details;
316 verify_details.cert_verify_result.verified_cert = test_cert;
317 verify_details.cert_verify_result.is_issued_by_known_root = true;
318 return verify_details;
319 }
320
NotifyIPAddressChanged()321 void QuicSessionPoolTestBase::NotifyIPAddressChanged() {
322 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
323 // Spin the message loop so the notification is delivered.
324 base::RunLoop().RunUntilIdle();
325 }
326
327 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerConnectionClosePacket(uint64_t num)328 QuicSessionPoolTestBase::ConstructServerConnectionClosePacket(uint64_t num) {
329 return server_maker_.Packet(num)
330 .AddConnectionCloseFrame(quic::QUIC_CRYPTO_VERSION_NOT_SUPPORTED,
331 "Time to panic!")
332 .Build();
333 }
334
335 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientRstPacket(uint64_t packet_number,quic::QuicRstStreamErrorCode error_code)336 QuicSessionPoolTestBase::ConstructClientRstPacket(
337 uint64_t packet_number,
338 quic::QuicRstStreamErrorCode error_code) {
339 quic::QuicStreamId stream_id = GetNthClientInitiatedBidirectionalStreamId(0);
340 return client_maker_.Packet(packet_number)
341 .AddStopSendingFrame(stream_id, error_code)
342 .AddRstStreamFrame(stream_id, error_code)
343 .Build();
344 }
345
346 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructGetRequestPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin)347 QuicSessionPoolTestBase::ConstructGetRequestPacket(uint64_t packet_number,
348 quic::QuicStreamId stream_id,
349 bool fin) {
350 quiche::HttpHeaderBlock headers =
351 client_maker_.GetRequestHeaders("GET", "https", "/");
352 spdy::SpdyPriority priority =
353 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
354 size_t spdy_headers_frame_len;
355 return client_maker_.MakeRequestHeadersPacket(packet_number, stream_id, fin,
356 priority, std::move(headers),
357 &spdy_headers_frame_len);
358 }
359
360 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructConnectUdpRequestPacket(uint64_t packet_number,quic::QuicStreamId stream_id,std::string authority,std::string path,bool fin)361 QuicSessionPoolTestBase::ConstructConnectUdpRequestPacket(
362 uint64_t packet_number,
363 quic::QuicStreamId stream_id,
364 std::string authority,
365 std::string path,
366 bool fin) {
367 return ConstructConnectUdpRequestPacket(client_maker_, packet_number,
368 stream_id, authority, path, fin);
369 }
370
371 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructConnectUdpRequestPacket(QuicTestPacketMaker & packet_maker,uint64_t packet_number,quic::QuicStreamId stream_id,std::string authority,std::string path,bool fin)372 QuicSessionPoolTestBase::ConstructConnectUdpRequestPacket(
373 QuicTestPacketMaker& packet_maker,
374 uint64_t packet_number,
375 quic::QuicStreamId stream_id,
376 std::string authority,
377 std::string path,
378 bool fin) {
379 quiche::HttpHeaderBlock headers;
380 headers[":scheme"] = "https";
381 headers[":path"] = path;
382 headers[":protocol"] = "connect-udp";
383 headers[":method"] = "CONNECT";
384 headers[":authority"] = authority;
385 headers["user-agent"] = "test-ua";
386 headers["capsule-protocol"] = "?1";
387 spdy::SpdyPriority priority =
388 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
389 size_t spdy_headers_frame_len;
390 auto rv = packet_maker.MakeRequestHeadersPacket(
391 packet_number, stream_id, fin, priority, std::move(headers),
392 &spdy_headers_frame_len, /*should_include_priority_frame=*/false);
393 return rv;
394 }
395
ConstructClientH3DatagramFrame(uint64_t quarter_stream_id,uint64_t context_id,std::unique_ptr<quic::QuicEncryptedPacket> inner)396 std::string QuicSessionPoolTestBase::ConstructClientH3DatagramFrame(
397 uint64_t quarter_stream_id,
398 uint64_t context_id,
399 std::unique_ptr<quic::QuicEncryptedPacket> inner) {
400 std::string data;
401 // Allow enough space for payload and two varint-62's.
402 data.resize(inner->length() + 2 * 8);
403 quiche::QuicheDataWriter writer(data.capacity(), data.data());
404 CHECK(writer.WriteVarInt62(quarter_stream_id));
405 CHECK(writer.WriteVarInt62(context_id));
406 CHECK(writer.WriteBytes(inner->data(), inner->length()));
407 data.resize(writer.length());
408 return data;
409 }
410
411 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructClientH3DatagramPacket(uint64_t packet_number,uint64_t quarter_stream_id,uint64_t context_id,std::unique_ptr<quic::QuicEncryptedPacket> inner)412 QuicSessionPoolTestBase::ConstructClientH3DatagramPacket(
413 uint64_t packet_number,
414 uint64_t quarter_stream_id,
415 uint64_t context_id,
416 std::unique_ptr<quic::QuicEncryptedPacket> inner) {
417 std::string data = ConstructClientH3DatagramFrame(
418 quarter_stream_id, context_id, std::move(inner));
419 return client_maker_.Packet(packet_number).AddMessageFrame(data).Build();
420 }
421
422 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructOkResponsePacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin)423 QuicSessionPoolTestBase::ConstructOkResponsePacket(uint64_t packet_number,
424 quic::QuicStreamId stream_id,
425 bool fin) {
426 return ConstructOkResponsePacket(server_maker_, packet_number, stream_id,
427 fin);
428 }
429
430 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructOkResponsePacket(QuicTestPacketMaker & packet_maker,uint64_t packet_number,quic::QuicStreamId stream_id,bool fin)431 QuicSessionPoolTestBase::ConstructOkResponsePacket(
432 QuicTestPacketMaker& packet_maker,
433 uint64_t packet_number,
434 quic::QuicStreamId stream_id,
435 bool fin) {
436 quiche::HttpHeaderBlock headers = packet_maker.GetResponseHeaders("200");
437 size_t spdy_headers_frame_len;
438 return packet_maker.MakeResponseHeadersPacket(packet_number, stream_id, fin,
439 std::move(headers),
440 &spdy_headers_frame_len);
441 }
442
443 std::unique_ptr<quic::QuicReceivedPacket>
ConstructInitialSettingsPacket()444 QuicSessionPoolTestBase::ConstructInitialSettingsPacket() {
445 return client_maker_.MakeInitialSettingsPacket(1);
446 }
447
448 std::unique_ptr<quic::QuicReceivedPacket>
ConstructInitialSettingsPacket(uint64_t packet_number)449 QuicSessionPoolTestBase::ConstructInitialSettingsPacket(
450 uint64_t packet_number) {
451 return client_maker_.MakeInitialSettingsPacket(packet_number);
452 }
453
454 std::unique_ptr<quic::QuicReceivedPacket>
ConstructInitialSettingsPacket(QuicTestPacketMaker & packet_maker,uint64_t packet_number)455 QuicSessionPoolTestBase::ConstructInitialSettingsPacket(
456 QuicTestPacketMaker& packet_maker,
457 uint64_t packet_number) {
458 return packet_maker.MakeInitialSettingsPacket(packet_number);
459 }
460
461 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerSettingsPacket(uint64_t packet_number)462 QuicSessionPoolTestBase::ConstructServerSettingsPacket(uint64_t packet_number) {
463 return server_maker_.MakeInitialSettingsPacket(packet_number);
464 }
465
466 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructAckPacket(test::QuicTestPacketMaker & packet_maker,uint64_t packet_number,uint64_t packet_num_received,uint64_t smallest_received,uint64_t largest_received)467 QuicSessionPoolTestBase::ConstructAckPacket(
468 test::QuicTestPacketMaker& packet_maker,
469 uint64_t packet_number,
470 uint64_t packet_num_received,
471 uint64_t smallest_received,
472 uint64_t largest_received) {
473 return packet_maker.Packet(packet_number)
474 .AddAckFrame(packet_num_received, smallest_received, largest_received)
475 .Build();
476 }
477
ConstructDataHeader(size_t body_len)478 std::string QuicSessionPoolTestBase::ConstructDataHeader(size_t body_len) {
479 quiche::QuicheBuffer buffer = quic::HttpEncoder::SerializeDataFrameHeader(
480 body_len, quiche::SimpleBufferAllocator::Get());
481 return std::string(buffer.data(), buffer.size());
482 }
483
484 std::unique_ptr<quic::QuicEncryptedPacket>
ConstructServerDataPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,std::string_view data)485 QuicSessionPoolTestBase::ConstructServerDataPacket(uint64_t packet_number,
486 quic::QuicStreamId stream_id,
487 bool fin,
488 std::string_view data) {
489 return server_maker_.Packet(packet_number)
490 .AddStreamFrame(stream_id, fin, data)
491 .Build();
492 }
493
ConstructH3Datagram(uint64_t stream_id,uint64_t context_id,std::unique_ptr<quic::QuicEncryptedPacket> packet)494 std::string QuicSessionPoolTestBase::ConstructH3Datagram(
495 uint64_t stream_id,
496 uint64_t context_id,
497 std::unique_ptr<quic::QuicEncryptedPacket> packet) {
498 std::string data;
499 // Allow enough space for payload and two varint-62's.
500 data.resize(packet->length() + 2 * 8);
501 quiche::QuicheDataWriter writer(data.capacity(), data.data());
502 CHECK(writer.WriteVarInt62(stream_id >> 2));
503 CHECK(writer.WriteVarInt62(context_id));
504 CHECK(writer.WriteBytes(packet->data(), packet->length()));
505 data.resize(writer.length());
506 return data;
507 }
508
509 quic::QuicStreamId
GetNthClientInitiatedBidirectionalStreamId(int n) const510 QuicSessionPoolTestBase::GetNthClientInitiatedBidirectionalStreamId(
511 int n) const {
512 return quic::test::GetNthClientInitiatedBidirectionalStreamId(
513 version_.transport_version, n);
514 }
515
GetQpackDecoderStreamId() const516 quic::QuicStreamId QuicSessionPoolTestBase::GetQpackDecoderStreamId() const {
517 return quic::test::GetNthClientInitiatedUnidirectionalStreamId(
518 version_.transport_version, 1);
519 }
520
StreamCancellationQpackDecoderInstruction(int n) const521 std::string QuicSessionPoolTestBase::StreamCancellationQpackDecoderInstruction(
522 int n) const {
523 return StreamCancellationQpackDecoderInstruction(n, true);
524 }
525
StreamCancellationQpackDecoderInstruction(int n,bool create_stream) const526 std::string QuicSessionPoolTestBase::StreamCancellationQpackDecoderInstruction(
527 int n,
528 bool create_stream) const {
529 const quic::QuicStreamId cancelled_stream_id =
530 GetNthClientInitiatedBidirectionalStreamId(n);
531 EXPECT_LT(cancelled_stream_id, 63u);
532
533 const char opcode = 0x40;
534 if (create_stream) {
535 return {0x03, static_cast<char>(opcode | cancelled_stream_id)};
536 } else {
537 return {static_cast<char>(opcode | cancelled_stream_id)};
538 }
539 }
540
541 quic::QuicStreamId
GetNthServerInitiatedUnidirectionalStreamId(int n)542 QuicSessionPoolTestBase::GetNthServerInitiatedUnidirectionalStreamId(int n) {
543 return quic::test::GetNthServerInitiatedUnidirectionalStreamId(
544 version_.transport_version, n);
545 }
546
OnFailedOnDefaultNetwork(int rv)547 void QuicSessionPoolTestBase::OnFailedOnDefaultNetwork(int rv) {
548 failed_on_default_network_ = true;
549 }
550
551 } // namespace net::test
552