• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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