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