xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/test_tools/quic_test_server.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2015 The Chromium Authors. All rights reserved.
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 "quiche/quic/test_tools/quic_test_server.h"
6 
7 #include <utility>
8 
9 #include "absl/memory/memory.h"
10 #include "absl/strings/string_view.h"
11 #include "quiche/quic/core/connection_id_generator.h"
12 #include "quiche/quic/core/io/quic_default_event_loop.h"
13 #include "quiche/quic/core/quic_default_connection_helper.h"
14 #include "quiche/quic/core/quic_types.h"
15 #include "quiche/quic/core/quic_versions.h"
16 #include "quiche/quic/tools/quic_simple_crypto_server_stream_helper.h"
17 #include "quiche/quic/tools/quic_simple_dispatcher.h"
18 #include "quiche/quic/tools/quic_simple_server_session.h"
19 
20 namespace quic {
21 
22 namespace test {
23 
24 class CustomStreamSession : public QuicSimpleServerSession {
25  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)26   CustomStreamSession(
27       const QuicConfig& config,
28       const ParsedQuicVersionVector& supported_versions,
29       QuicConnection* connection, QuicSession::Visitor* visitor,
30       QuicCryptoServerStreamBase::Helper* helper,
31       const QuicCryptoServerConfig* crypto_config,
32       QuicCompressedCertsCache* compressed_certs_cache,
33       QuicTestServer::StreamFactory* stream_factory,
34       QuicTestServer::CryptoStreamFactory* crypto_stream_factory,
35       QuicSimpleServerBackend* quic_simple_server_backend)
36       : QuicSimpleServerSession(config, supported_versions, connection, visitor,
37                                 helper, crypto_config, compressed_certs_cache,
38                                 quic_simple_server_backend),
39         stream_factory_(stream_factory),
40         crypto_stream_factory_(crypto_stream_factory) {}
41 
CreateIncomingStream(QuicStreamId id)42   QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
43     if (!ShouldCreateIncomingStream(id)) {
44       return nullptr;
45     }
46     if (stream_factory_) {
47       QuicSpdyStream* stream =
48           stream_factory_->CreateStream(id, this, server_backend());
49       ActivateStream(absl::WrapUnique(stream));
50       return stream;
51     }
52     return QuicSimpleServerSession::CreateIncomingStream(id);
53   }
54 
CreateQuicCryptoServerStream(const QuicCryptoServerConfig * crypto_config,QuicCompressedCertsCache * compressed_certs_cache)55   std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
56       const QuicCryptoServerConfig* crypto_config,
57       QuicCompressedCertsCache* compressed_certs_cache) override {
58     if (crypto_stream_factory_) {
59       return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
60     }
61     return QuicSimpleServerSession::CreateQuicCryptoServerStream(
62         crypto_config, compressed_certs_cache);
63   }
64 
65  private:
66   QuicTestServer::StreamFactory* stream_factory_;               // Not owned.
67   QuicTestServer::CryptoStreamFactory* crypto_stream_factory_;  // Not owned.
68 };
69 
70 class QuicTestDispatcher : public QuicSimpleDispatcher {
71  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,ConnectionIdGeneratorInterface & generator)72   QuicTestDispatcher(
73       const QuicConfig* config, const QuicCryptoServerConfig* crypto_config,
74       QuicVersionManager* version_manager,
75       std::unique_ptr<QuicConnectionHelperInterface> helper,
76       std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
77       std::unique_ptr<QuicAlarmFactory> alarm_factory,
78       QuicSimpleServerBackend* quic_simple_server_backend,
79       uint8_t expected_server_connection_id_length,
80       ConnectionIdGeneratorInterface& generator)
81       : QuicSimpleDispatcher(config, crypto_config, version_manager,
82                              std::move(helper), std::move(session_helper),
83                              std::move(alarm_factory),
84                              quic_simple_server_backend,
85                              expected_server_connection_id_length, generator),
86         session_factory_(nullptr),
87         stream_factory_(nullptr),
88         crypto_stream_factory_(nullptr) {}
89 
CreateQuicSession(QuicConnectionId id,const QuicSocketAddress & self_address,const QuicSocketAddress & peer_address,absl::string_view alpn,const ParsedQuicVersion & version,const ParsedClientHello &,ConnectionIdGeneratorInterface & connection_id_generator)90   std::unique_ptr<QuicSession> CreateQuicSession(
91       QuicConnectionId id, const QuicSocketAddress& self_address,
92       const QuicSocketAddress& peer_address, absl::string_view alpn,
93       const ParsedQuicVersion& version,
94       const ParsedClientHello& /*parsed_chlo*/,
95       ConnectionIdGeneratorInterface& connection_id_generator) override {
96     QuicReaderMutexLock lock(&factory_lock_);
97     // The QuicServerSessionBase takes ownership of |connection| below.
98     QuicConnection* connection = new QuicConnection(
99         id, self_address, peer_address, helper(), alarm_factory(), writer(),
100         /* owns_writer= */ false, Perspective::IS_SERVER,
101         ParsedQuicVersionVector{version}, connection_id_generator);
102 
103     std::unique_ptr<QuicServerSessionBase> session;
104     if (session_factory_ == nullptr && stream_factory_ == nullptr &&
105         crypto_stream_factory_ == nullptr) {
106       session = std::make_unique<QuicSimpleServerSession>(
107           config(), GetSupportedVersions(), connection, this, session_helper(),
108           crypto_config(), compressed_certs_cache(), server_backend());
109     } else if (stream_factory_ != nullptr ||
110                crypto_stream_factory_ != nullptr) {
111       session = std::make_unique<CustomStreamSession>(
112           config(), GetSupportedVersions(), connection, this, session_helper(),
113           crypto_config(), compressed_certs_cache(), stream_factory_,
114           crypto_stream_factory_, server_backend());
115     } else {
116       session = session_factory_->CreateSession(
117           config(), connection, this, session_helper(), crypto_config(),
118           compressed_certs_cache(), server_backend(), alpn);
119     }
120     if (VersionUsesHttp3(version.transport_version)) {
121       QUICHE_DCHECK(session->allow_extended_connect());
122       // Do not allow extended CONNECT request if the backend doesn't support
123       // it.
124       session->set_allow_extended_connect(
125           server_backend()->SupportsExtendedConnect());
126     }
127     session->Initialize();
128     return session;
129   }
130 
SetSessionFactory(QuicTestServer::SessionFactory * factory)131   void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
132     QuicWriterMutexLock lock(&factory_lock_);
133     QUICHE_DCHECK(session_factory_ == nullptr);
134     QUICHE_DCHECK(stream_factory_ == nullptr);
135     QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
136     session_factory_ = factory;
137   }
138 
SetStreamFactory(QuicTestServer::StreamFactory * factory)139   void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
140     QuicWriterMutexLock lock(&factory_lock_);
141     QUICHE_DCHECK(session_factory_ == nullptr);
142     QUICHE_DCHECK(stream_factory_ == nullptr);
143     stream_factory_ = factory;
144   }
145 
SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory * factory)146   void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
147     QuicWriterMutexLock lock(&factory_lock_);
148     QUICHE_DCHECK(session_factory_ == nullptr);
149     QUICHE_DCHECK(crypto_stream_factory_ == nullptr);
150     crypto_stream_factory_ = factory;
151   }
152 
153  private:
154   QuicMutex factory_lock_;
155   QuicTestServer::SessionFactory* session_factory_;             // Not owned.
156   QuicTestServer::StreamFactory* stream_factory_;               // Not owned.
157   QuicTestServer::CryptoStreamFactory* crypto_stream_factory_;  // Not owned.
158 };
159 
QuicTestServer(std::unique_ptr<ProofSource> proof_source,QuicSimpleServerBackend * quic_simple_server_backend)160 QuicTestServer::QuicTestServer(
161     std::unique_ptr<ProofSource> proof_source,
162     QuicSimpleServerBackend* quic_simple_server_backend)
163     : QuicServer(std::move(proof_source), quic_simple_server_backend) {}
164 
QuicTestServer(std::unique_ptr<ProofSource> proof_source,const QuicConfig & config,const ParsedQuicVersionVector & supported_versions,QuicSimpleServerBackend * quic_simple_server_backend)165 QuicTestServer::QuicTestServer(
166     std::unique_ptr<ProofSource> proof_source, const QuicConfig& config,
167     const ParsedQuicVersionVector& supported_versions,
168     QuicSimpleServerBackend* quic_simple_server_backend)
169     : QuicTestServer(std::move(proof_source), config, supported_versions,
170                      quic_simple_server_backend,
171                      kQuicDefaultConnectionIdLength) {}
172 
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)173 QuicTestServer::QuicTestServer(
174     std::unique_ptr<ProofSource> proof_source, const QuicConfig& config,
175     const ParsedQuicVersionVector& supported_versions,
176     QuicSimpleServerBackend* quic_simple_server_backend,
177     uint8_t expected_server_connection_id_length)
178     : QuicServer(std::move(proof_source), config,
179                  QuicCryptoServerConfig::ConfigOptions(), supported_versions,
180                  quic_simple_server_backend,
181                  expected_server_connection_id_length) {}
182 
CreateQuicDispatcher()183 QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
184   return new QuicTestDispatcher(
185       &config(), &crypto_config(), version_manager(),
186       std::make_unique<QuicDefaultConnectionHelper>(),
187       std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
188           new QuicSimpleCryptoServerStreamHelper()),
189       event_loop()->CreateAlarmFactory(), server_backend(),
190       expected_server_connection_id_length(), connection_id_generator());
191 }
192 
SetSessionFactory(SessionFactory * factory)193 void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
194   QUICHE_DCHECK(dispatcher());
195   static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
196 }
197 
SetSpdyStreamFactory(StreamFactory * factory)198 void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
199   static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
200 }
201 
SetCryptoStreamFactory(CryptoStreamFactory * factory)202 void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
203   static_cast<QuicTestDispatcher*>(dispatcher())
204       ->SetCryptoStreamFactory(factory);
205 }
206 
SetEventLoopFactory(QuicEventLoopFactory * factory)207 void QuicTestServer::SetEventLoopFactory(QuicEventLoopFactory* factory) {
208   event_loop_factory_ = factory;
209 }
210 
CreateEventLoop()211 std::unique_ptr<QuicEventLoop> QuicTestServer::CreateEventLoop() {
212   QuicEventLoopFactory* factory = event_loop_factory_;
213   if (factory == nullptr) {
214     factory = GetDefaultEventLoop();
215   }
216   return factory->Create(QuicDefaultClock::Get());
217 }
218 
219 ///////////////////////////   TEST SESSIONS ///////////////////////////////
220 
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)221 ImmediateGoAwaySession::ImmediateGoAwaySession(
222     const QuicConfig& config, QuicConnection* connection,
223     QuicSession::Visitor* visitor, QuicCryptoServerStreamBase::Helper* helper,
224     const QuicCryptoServerConfig* crypto_config,
225     QuicCompressedCertsCache* compressed_certs_cache,
226     QuicSimpleServerBackend* quic_simple_server_backend)
227     : QuicSimpleServerSession(
228           config, CurrentSupportedVersions(), connection, visitor, helper,
229           crypto_config, compressed_certs_cache, quic_simple_server_backend) {}
230 
OnStreamFrame(const QuicStreamFrame & frame)231 void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
232   if (VersionUsesHttp3(transport_version())) {
233     SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
234   } else {
235     SendGoAway(QUIC_PEER_GOING_AWAY, "");
236   }
237   QuicSimpleServerSession::OnStreamFrame(frame);
238 }
239 
OnCryptoFrame(const QuicCryptoFrame & frame)240 void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) {
241   // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. It's sent in a QUIC stream
242   // and requires encryption. Thus the sending is done in
243   // OnNewEncryptionKeyAvailable().
244   if (!VersionUsesHttp3(transport_version())) {
245     SendGoAway(QUIC_PEER_GOING_AWAY, "");
246   }
247   QuicSimpleServerSession::OnCryptoFrame(frame);
248 }
249 
OnNewEncryptionKeyAvailable(EncryptionLevel level,std::unique_ptr<QuicEncrypter> encrypter)250 void ImmediateGoAwaySession::OnNewEncryptionKeyAvailable(
251     EncryptionLevel level, std::unique_ptr<QuicEncrypter> encrypter) {
252   QuicSimpleServerSession::OnNewEncryptionKeyAvailable(level,
253                                                        std::move(encrypter));
254   if (VersionUsesHttp3(transport_version())) {
255     if (IsEncryptionEstablished() && !goaway_sent()) {
256       SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
257     }
258   }
259 }
260 
261 }  // namespace test
262 
263 }  // namespace quic
264