blob: 59fac5d9a4c64cc5113f295579e1fb13499f2646 [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
QUICHE team5be974e2020-12-29 18:35:24 -05005#include "quic/test_tools/quic_test_server.h"
QUICHE teama6ef0a62019-03-07 20:34:33 -05006
bnc463f2352019-10-10 04:49:34 -07007#include <utility>
8
vasilvv5f225b02020-10-08 11:49:09 -04009#include "absl/strings/string_view.h"
QUICHE team5be974e2020-12-29 18:35:24 -050010#include "quic/core/quic_epoll_alarm_factory.h"
11#include "quic/core/quic_epoll_connection_helper.h"
12#include "quic/platform/api/quic_ptr_util.h"
13#include "quic/tools/quic_simple_crypto_server_stream_helper.h"
14#include "quic/tools/quic_simple_dispatcher.h"
15#include "quic/tools/quic_simple_server_session.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,
nharper5f23a2d2020-02-20 10:44:09 -080028 QuicCryptoServerStreamBase::Helper* helper,
QUICHE teama6ef0a62019-03-07 20:34:33 -050029 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,
nharper5f23a2d2020-02-20 10:44:09 -080080 std::unique_ptr<QuicCryptoServerStreamBase::Helper> session_helper,
QUICHE teama6ef0a62019-03-07 20:34:33 -050081 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,
wub4e3fb902020-07-15 13:37:29 -070098 const QuicSocketAddress& self_address,
99 const QuicSocketAddress& peer_address,
vasilvv5f225b02020-10-08 11:49:09 -0400100 absl::string_view alpn,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500101 const ParsedQuicVersion& version) override {
102 QuicReaderMutexLock lock(&factory_lock_);
103 if (session_factory_ == nullptr && stream_factory_ == nullptr &&
104 crypto_stream_factory_ == nullptr) {
wub4e3fb902020-07-15 13:37:29 -0700105 return QuicSimpleDispatcher::CreateQuicSession(
106 id, self_address, peer_address, alpn, version);
QUICHE teama6ef0a62019-03-07 20:34:33 -0500107 }
wub4e3fb902020-07-15 13:37:29 -0700108 QuicConnection* connection = new QuicConnection(
wub5df36632020-10-01 14:42:17 -0700109 id, self_address, peer_address, helper(), alarm_factory(), writer(),
wub4e3fb902020-07-15 13:37:29 -0700110 /* owns_writer= */ false, Perspective::IS_SERVER,
111 ParsedQuicVersionVector{version});
QUICHE teama6ef0a62019-03-07 20:34:33 -0500112
wub89490e02019-12-12 12:45:58 -0800113 std::unique_ptr<QuicServerSessionBase> session;
QUICHE teama6ef0a62019-03-07 20:34:33 -0500114 if (stream_factory_ != nullptr || crypto_stream_factory_ != nullptr) {
wub89490e02019-12-12 12:45:58 -0800115 session = std::make_unique<CustomStreamSession>(
QUICHE teama6ef0a62019-03-07 20:34:33 -0500116 config(), GetSupportedVersions(), connection, this, session_helper(),
117 crypto_config(), compressed_certs_cache(), stream_factory_,
118 crypto_stream_factory_, server_backend());
119 } else {
120 session = session_factory_->CreateSession(
121 config(), connection, this, session_helper(), crypto_config(),
122 compressed_certs_cache(), server_backend());
123 }
124 session->Initialize();
125 return session;
126 }
127
128 void SetSessionFactory(QuicTestServer::SessionFactory* factory) {
129 QuicWriterMutexLock lock(&factory_lock_);
130 DCHECK(session_factory_ == nullptr);
131 DCHECK(stream_factory_ == nullptr);
132 DCHECK(crypto_stream_factory_ == nullptr);
133 session_factory_ = factory;
134 }
135
136 void SetStreamFactory(QuicTestServer::StreamFactory* factory) {
137 QuicWriterMutexLock lock(&factory_lock_);
138 DCHECK(session_factory_ == nullptr);
139 DCHECK(stream_factory_ == nullptr);
140 stream_factory_ = factory;
141 }
142
143 void SetCryptoStreamFactory(QuicTestServer::CryptoStreamFactory* factory) {
144 QuicWriterMutexLock lock(&factory_lock_);
145 DCHECK(session_factory_ == nullptr);
146 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
157QuicTestServer::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
162QuicTestServer::QuicTestServer(
163 std::unique_ptr<ProofSource> proof_source,
164 const QuicConfig& config,
165 const ParsedQuicVersionVector& supported_versions,
166 QuicSimpleServerBackend* quic_simple_server_backend)
167 : QuicTestServer(std::move(proof_source),
168 config,
169 supported_versions,
170 quic_simple_server_backend,
171 kQuicDefaultConnectionIdLength) {}
172
173QuicTestServer::QuicTestServer(
174 std::unique_ptr<ProofSource> proof_source,
175 const QuicConfig& config,
176 const ParsedQuicVersionVector& supported_versions,
177 QuicSimpleServerBackend* quic_simple_server_backend,
dschinazi8ff74822019-05-28 16:37:20 -0700178 uint8_t expected_server_connection_id_length)
QUICHE teama6ef0a62019-03-07 20:34:33 -0500179 : QuicServer(std::move(proof_source),
180 config,
181 QuicCryptoServerConfig::ConfigOptions(),
182 supported_versions,
183 quic_simple_server_backend,
dschinazi8ff74822019-05-28 16:37:20 -0700184 expected_server_connection_id_length) {}
QUICHE teama6ef0a62019-03-07 20:34:33 -0500185
186QuicDispatcher* QuicTestServer::CreateQuicDispatcher() {
187 return new QuicTestDispatcher(
188 &config(), &crypto_config(), version_manager(),
vasilvv0fc587f2019-09-06 13:33:08 -0700189 std::make_unique<QuicEpollConnectionHelper>(epoll_server(),
190 QuicAllocator::BUFFER_POOL),
nharper5f23a2d2020-02-20 10:44:09 -0800191 std::unique_ptr<QuicCryptoServerStreamBase::Helper>(
wub662a3d62019-08-16 14:10:50 -0700192 new QuicSimpleCryptoServerStreamHelper()),
vasilvv0fc587f2019-09-06 13:33:08 -0700193 std::make_unique<QuicEpollAlarmFactory>(epoll_server()), server_backend(),
dschinazi8ff74822019-05-28 16:37:20 -0700194 expected_server_connection_id_length());
QUICHE teama6ef0a62019-03-07 20:34:33 -0500195}
196
197void QuicTestServer::SetSessionFactory(SessionFactory* factory) {
198 DCHECK(dispatcher());
199 static_cast<QuicTestDispatcher*>(dispatcher())->SetSessionFactory(factory);
200}
201
202void QuicTestServer::SetSpdyStreamFactory(StreamFactory* factory) {
203 static_cast<QuicTestDispatcher*>(dispatcher())->SetStreamFactory(factory);
204}
205
206void QuicTestServer::SetCryptoStreamFactory(CryptoStreamFactory* factory) {
207 static_cast<QuicTestDispatcher*>(dispatcher())
208 ->SetCryptoStreamFactory(factory);
209}
210
211/////////////////////////// TEST SESSIONS ///////////////////////////////
212
213ImmediateGoAwaySession::ImmediateGoAwaySession(
214 const QuicConfig& config,
215 QuicConnection* connection,
216 QuicSession::Visitor* visitor,
nharper5f23a2d2020-02-20 10:44:09 -0800217 QuicCryptoServerStreamBase::Helper* helper,
QUICHE teama6ef0a62019-03-07 20:34:33 -0500218 const QuicCryptoServerConfig* crypto_config,
219 QuicCompressedCertsCache* compressed_certs_cache,
220 QuicSimpleServerBackend* quic_simple_server_backend)
221 : QuicSimpleServerSession(config,
222 CurrentSupportedVersions(),
223 connection,
224 visitor,
225 helper,
226 crypto_config,
227 compressed_certs_cache,
228 quic_simple_server_backend) {}
229
230void ImmediateGoAwaySession::OnStreamFrame(const QuicStreamFrame& frame) {
renjietang686ce582019-10-17 14:28:16 -0700231 if (VersionUsesHttp3(transport_version())) {
fayangb6daf212020-12-08 12:00:40 -0800232 SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
renjietang686ce582019-10-17 14:28:16 -0700233 } else {
234 SendGoAway(QUIC_PEER_GOING_AWAY, "");
235 }
QUICHE teama6ef0a62019-03-07 20:34:33 -0500236 QuicSimpleServerSession::OnStreamFrame(frame);
237}
238
nharpere5415ca2019-10-04 15:14:54 -0700239void ImmediateGoAwaySession::OnCryptoFrame(const QuicCryptoFrame& frame) {
renjietangd538f022020-05-11 11:29:42 -0700240 // In IETF QUIC, GOAWAY lives up in HTTP/3 layer. It's sent in a QUIC stream
241 // and requires encryption. Thus the sending is done in
242 // OnNewEncryptionKeyAvailable().
renjietang686ce582019-10-17 14:28:16 -0700243 if (!VersionUsesHttp3(transport_version())) {
244 SendGoAway(QUIC_PEER_GOING_AWAY, "");
245 }
nharpere5415ca2019-10-04 15:14:54 -0700246 QuicSimpleServerSession::OnCryptoFrame(frame);
247}
248
renjietangd538f022020-05-11 11:29:42 -0700249void ImmediateGoAwaySession::OnNewEncryptionKeyAvailable(
250 EncryptionLevel level,
251 std::unique_ptr<QuicEncrypter> encrypter) {
252 QuicSimpleServerSession::OnNewEncryptionKeyAvailable(level,
253 std::move(encrypter));
254 if (VersionUsesHttp3(transport_version())) {
bnc3988f572020-08-27 05:27:04 -0700255 if (IsEncryptionEstablished() && !goaway_sent()) {
fayangb6daf212020-12-08 12:00:40 -0800256 SendHttp3GoAway(QUIC_PEER_GOING_AWAY, "");
renjietangd538f022020-05-11 11:29:42 -0700257 }
258 }
259}
260
QUICHE teama6ef0a62019-03-07 20:34:33 -0500261} // namespace test
262
263} // namespace quic