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