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