blob: 147d85e32391c3fe98fd920682767737278679fc [file] [log] [blame]
QUICHE teama6ef0a62019-03-07 20:34:33 -05001// 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 "net/third_party/quiche/src/quic/test_tools/quic_test_server.h"
6
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
QUICHE teama6ef0a62019-03-07 20:34:33 -05009#include "net/third_party/quiche/src/quic/core/quic_epoll_alarm_factory.h"
10#include "net/third_party/quiche/src/quic/core/quic_epoll_connection_helper.h"
11#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
12#include "net/third_party/quiche/src/quic/tools/quic_simple_crypto_server_stream_helper.h"
13#include "net/third_party/quiche/src/quic/tools/quic_simple_dispatcher.h"
14#include "net/third_party/quiche/src/quic/tools/quic_simple_server_session.h"
QUICHE team6dcf6ab2019-12-11 10:10:51 -080015#include "net/third_party/quiche/src/common/platform/api/quiche_string_piece.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -050016
17namespace quic {
18
19namespace test {
20
21class CustomStreamSession : public QuicSimpleServerSession {
22 public:
23 CustomStreamSession(
24 const QuicConfig& config,
25 const ParsedQuicVersionVector& supported_versions,
26 QuicConnection* connection,
27 QuicSession::Visitor* visitor,
28 QuicCryptoServerStream::Helper* helper,
29 const QuicCryptoServerConfig* crypto_config,
30 QuicCompressedCertsCache* compressed_certs_cache,
31 QuicTestServer::StreamFactory* stream_factory,
32 QuicTestServer::CryptoStreamFactory* crypto_stream_factory,
33 QuicSimpleServerBackend* quic_simple_server_backend)
34 : QuicSimpleServerSession(config,
35 supported_versions,
36 connection,
37 visitor,
38 helper,
39 crypto_config,
40 compressed_certs_cache,
41 quic_simple_server_backend),
42 stream_factory_(stream_factory),
43 crypto_stream_factory_(crypto_stream_factory) {}
44
45 QuicSpdyStream* CreateIncomingStream(QuicStreamId id) override {
46 if (!ShouldCreateIncomingStream(id)) {
47 return nullptr;
48 }
49 if (stream_factory_) {
50 QuicSpdyStream* stream =
51 stream_factory_->CreateStream(id, this, server_backend());
52 ActivateStream(QuicWrapUnique(stream));
53 return stream;
54 }
55 return QuicSimpleServerSession::CreateIncomingStream(id);
56 }
57
nharpere5e28f92020-01-03 14:10:07 -080058 std::unique_ptr<QuicCryptoServerStreamBase> CreateQuicCryptoServerStream(
QUICHE teama6ef0a62019-03-07 20:34:33 -050059 const QuicCryptoServerConfig* crypto_config,
60 QuicCompressedCertsCache* compressed_certs_cache) override {
61 if (crypto_stream_factory_) {
62 return crypto_stream_factory_->CreateCryptoStream(crypto_config, this);
63 }
64 return QuicSimpleServerSession::CreateQuicCryptoServerStream(
65 crypto_config, compressed_certs_cache);
66 }
67
68 private:
69 QuicTestServer::StreamFactory* stream_factory_; // Not owned.
70 QuicTestServer::CryptoStreamFactory* crypto_stream_factory_; // Not owned.
71};
72
73class QuicTestDispatcher : public QuicSimpleDispatcher {
74 public:
75 QuicTestDispatcher(
76 const QuicConfig* config,
77 const QuicCryptoServerConfig* crypto_config,
78 QuicVersionManager* version_manager,
79 std::unique_ptr<QuicConnectionHelperInterface> helper,
80 std::unique_ptr<QuicCryptoServerStream::Helper> session_helper,
81 std::unique_ptr<QuicAlarmFactory> alarm_factory,
82 QuicSimpleServerBackend* quic_simple_server_backend,
dschinazi8ff74822019-05-28 16:37:20 -070083 uint8_t expected_server_connection_id_length)
QUICHE teama6ef0a62019-03-07 20:34:33 -050084 : QuicSimpleDispatcher(config,
85 crypto_config,
86 version_manager,
87 std::move(helper),
88 std::move(session_helper),
89 std::move(alarm_factory),
90 quic_simple_server_backend,
dschinazi8ff74822019-05-28 16:37:20 -070091 expected_server_connection_id_length),
QUICHE teama6ef0a62019-03-07 20:34:33 -050092 session_factory_(nullptr),
93 stream_factory_(nullptr),
94 crypto_stream_factory_(nullptr) {}
95
wub89490e02019-12-12 12:45:58 -080096 std::unique_ptr<QuicSession> CreateQuicSession(
QUICHE teama6ef0a62019-03-07 20:34:33 -050097 QuicConnectionId id,
98 const QuicSocketAddress& client,
QUICHE team6dcf6ab2019-12-11 10:10:51 -080099 quiche::QuicheStringPiece alpn,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500100 const ParsedQuicVersion& version) override {
101 QuicReaderMutexLock lock(&factory_lock_);
102 if (session_factory_ == nullptr && stream_factory_ == nullptr &&
103 crypto_stream_factory_ == nullptr) {
104 return QuicSimpleDispatcher::CreateQuicSession(id, client, alpn, version);
105 }
106 QuicConnection* connection =
107 new QuicConnection(id, client, helper(), alarm_factory(), writer(),
108 /* owns_writer= */ false, Perspective::IS_SERVER,
109 ParsedQuicVersionVector{version});
110
wub89490e02019-12-12 12:45:58 -0800111 std::unique_ptr<QuicServerSessionBase> session;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112 if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
wub89490e02019-12-12 12:45:58 -0800113 session = std::make_unique<CustomStreamSession>(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114 config(), GetSupportedVersions(), connection, this, session_helper(),
115 crypto_config(), compressed_certs_cache(), stream_factory_,
116 crypto_stream_factory_, server_backend());
117 } else {
118 session = session_factory_->CreateSession(
119 config(), connection, this, session_helper(), crypto_config(),
120 compressed_certs_cache(), server_backend());
121 }
rch4e7e60f2019-10-16 07:24:00 -0700122 // TODO(b/142715651): Figure out how to use QPACK in tests.
123 // Do not use the QPACK dynamic table in tests to avoid flakiness due to the
124 // uncertain order of receiving the SETTINGS frame and sending headers.
125 session->set_qpack_maximum_dynamic_table_capacity(0);
126 session->set_qpack_maximum_blocked_streams(0);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500127 session->Initialize();
128 return session;
129 }
130
131 void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
132 QuicWriterMutexLock lock(&factory_lock_);
133 DCHECK(session_factory_ == nullptr);
134 DCHECK(stream_factory_ == nullptr);
135 DCHECK(crypto_stream_factory_ == nullptr);
136 session_factory_ = factory;
137 }
138
139 void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
140 QuicWriterMutexLock lock(&factory_lock_);
141 DCHECK(session_factory_ == nullptr);
142 DCHECK(stream_factory_ == nullptr);
143 stream_factory_ = factory;
144 }
145
146 void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
147 QuicWriterMutexLock lock(&factory_lock_);
148 DCHECK(session_factory_ == nullptr);
149 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
160QuicTestServer::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
165QuicTestServer::QuicTestServer(
166 std::unique_ptr<ProofSource> proof_source,
167 const QuicConfig& config,
168 const ParsedQuicVersionVector& supported_versions,
169 QuicSimpleServerBackend* quic_simple_server_backend)
170 : QuicTestServer(std::move(proof_source),
171 config,
172 supported_versions,
173 quic_simple_server_backend,
174 kQuicDefaultConnectionIdLength) {}
175
176QuicTestServer::QuicTestServer(
177 std::unique_ptr<ProofSource> proof_source,
178 const QuicConfig& config,
179 const ParsedQuicVersionVector& supported_versions,
180 QuicSimpleServerBackend* quic_simple_server_backend,
dschinazi8ff74822019-05-28 16:37:20 -0700181 uint8_t expected_server_connection_id_length)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500182 : QuicServer(std::move(proof_source),
183 config,
184 QuicCryptoServerConfig::ConfigOptions(),
185 supported_versions,
186 quic_simple_server_backend,
dschinazi8ff74822019-05-28 16:37:20 -0700187 expected_server_connection_id_length) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500188
189QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
190 return new QuicTestDispatcher(
191 &config(), &crypto_config(), version_manager(),
vasilvv0fc587f2019-09-06 13:33:08 -0700192 std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
193 QuicAllocator::BUFFER_POOL),
QUICHE teama6ef0a62019-03-07 20:34:33 -0500194 std::unique_ptr<QuicCryptoServerStream::Helper>(
wub662a3d62019-08-16 14:10:50 -0700195 new QuicSimpleCryptoServerStreamHelper()),
vasilvv0fc587f2019-09-06 13:33:08 -0700196 std::make_unique<QuicEpollAlarmFactory>(epoll_server()), server_backend(),
dschinazi8ff74822019-05-28 16:37:20 -0700197 expected_server_connection_id_length());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500198}
199
200void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
201 DCHECK(dispatcher());
202 static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
203}
204
205void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
206 static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
207}
208
209void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
210 static_cast<QuicTestDispatcher*>(dispatcher())
211 ->SetCryptoStreamFactory(factory);
212}
213
214/////////////////////////// TEST SESSIONS ///////////////////////////////
215
216ImmediateGoAwaySession::ImmediateGoAwaySession(
217 const QuicConfig& config,
218 QuicConnection* connection,
219 QuicSession::Visitor* visitor,
220 QuicCryptoServerStream::Helper* helper,
221 const QuicCryptoServerConfig* crypto_config,
222 QuicCompressedCertsCache* compressed_certs_cache,
223 QuicSimpleServerBackend* quic_simple_server_backend)
224 : QuicSimpleServerSession(config,
225 CurrentSupportedVersions(),
226 connection,
227 visitor,
228 helper,
229 crypto_config,
230 compressed_certs_cache,
231 quic_simple_server_backend) {}
232
233void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
renjietang686ce582019-10-17 14:28:16 -0700234 if (VersionUsesHttp3(transport_version())) {
235 SendHttp3GoAway();
236 } else {
237 SendGoAway(QUIC_PEER_GOING_AWAY, "");
238 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500239 QuicSimpleServerSession::OnStreamFrame(frame);
240}
241
nharpere5415ca2019-10-04 15:14:54 -0700242void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) {
renjietang686ce582019-10-17 14:28:16 -0700243 // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. Even if it's a immediate
244 // goaway session, goaway shouldn't be sent when crypto frame is received.
245 if (!VersionUsesHttp3(transport_version())) {
246 SendGoAway(QUIC_PEER_GOING_AWAY, "");
247 }
nharpere5415ca2019-10-04 15:14:54 -0700248 QuicSimpleServerSession::OnCryptoFrame(frame);
249}
250
QUICHE teama6ef0a62019-03-07 20:34:33 -0500251} // namespace test
252
253} // namespace quic