blob: 48f1c77e7f08a465fa1a8e9ef608b9094a266011 [file] [log] [blame]
[email protected]1e960032013-12-20 19:00:201// Copyright 2013 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
Ryan Hamiltona3ee93a72018-08-01 22:03:085#include "net/quic/quic_test_packet_maker.h"
[email protected]1e960032013-12-20 19:00:206
rtenneti4b06ae72014-08-26 03:43:437#include <list>
bnc086b39e12016-06-24 13:05:268#include <utility>
rtenneti4b06ae72014-08-26 03:43:439
Bence Békyc7a29c02019-08-07 02:26:3410#include "base/strings/strcat.h"
11#include "base/strings/string_number_conversions.h"
Zhongyi Shi879659422018-08-02 17:58:2512#include "net/quic/mock_crypto_client_stream.h"
Bence Béky3a76c142019-07-16 23:53:1613#include "net/quic/quic_chromium_client_session.h"
Ryan Hamiltona3ee93a72018-08-01 22:03:0814#include "net/quic/quic_http_utils.h"
Bence Békyd3074402019-07-18 03:07:5515#include "net/third_party/quiche/src/quic/core/http/http_constants.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5116#include "net/third_party/quiche/src/quic/core/quic_framer.h"
17#include "net/third_party/quiche/src/quic/core/quic_utils.h"
18#include "net/third_party/quiche/src/quic/test_tools/mock_random.h"
19#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"
20#include "net/third_party/quiche/src/quic/test_tools/simple_data_producer.h"
[email protected]1e960032013-12-20 19:00:2021
22namespace net {
23namespace test {
Michael Warres74ee3ce2017-10-09 15:26:3724namespace {
[email protected]1e960032013-12-20 19:00:2025
Fan Yangac867502019-01-28 21:10:2326quic::QuicAckFrame MakeAckFrame(uint64_t largest_observed) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:5227 quic::QuicAckFrame ack;
Fan Yangac867502019-01-28 21:10:2328 ack.largest_acked = quic::QuicPacketNumber(largest_observed);
Michael Warres74ee3ce2017-10-09 15:26:3729 return ack;
30}
31
Ryan Hamiltone940bd12019-06-30 02:46:4532quic::QuicFrames CloneFrames(const quic::QuicFrames& frames) {
33 quic::QuicFrames new_frames = frames;
34 for (auto& frame : new_frames) {
35 switch (frame.type) {
36 // Frames smaller than a pointer are inlined, so don't need to be cloned.
37 case quic::PADDING_FRAME:
38 case quic::MTU_DISCOVERY_FRAME:
39 case quic::PING_FRAME:
40 case quic::MAX_STREAMS_FRAME:
41 case quic::STOP_WAITING_FRAME:
42 case quic::STREAMS_BLOCKED_FRAME:
43 case quic::STREAM_FRAME:
44 break;
45 case quic::ACK_FRAME:
46 frame.ack_frame = new quic::QuicAckFrame(*frame.ack_frame);
47 break;
48 case quic::RST_STREAM_FRAME:
49 frame.rst_stream_frame =
50 new quic::QuicRstStreamFrame(*frame.rst_stream_frame);
51 break;
52 case quic::CONNECTION_CLOSE_FRAME:
53 frame.connection_close_frame =
54 new quic::QuicConnectionCloseFrame(*frame.connection_close_frame);
55 break;
56 case quic::GOAWAY_FRAME:
57 frame.goaway_frame = new quic::QuicGoAwayFrame(*frame.goaway_frame);
58 break;
59 case quic::BLOCKED_FRAME:
60 frame.blocked_frame = new quic::QuicBlockedFrame(*frame.blocked_frame);
61 break;
62 case quic::WINDOW_UPDATE_FRAME:
63 frame.window_update_frame =
64 new quic::QuicWindowUpdateFrame(*frame.window_update_frame);
65 break;
66 case quic::PATH_CHALLENGE_FRAME:
67 frame.path_challenge_frame =
68 new quic::QuicPathChallengeFrame(*frame.path_challenge_frame);
69 break;
70 case quic::STOP_SENDING_FRAME:
71 frame.stop_sending_frame =
72 new quic::QuicStopSendingFrame(*frame.stop_sending_frame);
73 break;
74 case quic::NEW_CONNECTION_ID_FRAME:
75 frame.new_connection_id_frame =
76 new quic::QuicNewConnectionIdFrame(*frame.new_connection_id_frame);
77 break;
78 case quic::RETIRE_CONNECTION_ID_FRAME:
79 frame.retire_connection_id_frame =
80 new quic::QuicRetireConnectionIdFrame(
81 *frame.retire_connection_id_frame);
82 break;
83 case quic::PATH_RESPONSE_FRAME:
84 frame.path_response_frame =
85 new quic::QuicPathResponseFrame(*frame.path_response_frame);
86 break;
87 case quic::MESSAGE_FRAME:
88 DCHECK(false) << "Message frame not supported";
89 // frame.message_frame = new
90 // quic::QuicMessageFrame(*frame.message_frame);
91 break;
92 case quic::CRYPTO_FRAME:
93 frame.crypto_frame = new quic::QuicCryptoFrame(*frame.crypto_frame);
94 break;
95 case quic::NEW_TOKEN_FRAME:
96 frame.new_token_frame =
97 new quic::QuicNewTokenFrame(*frame.new_token_frame);
98 break;
99
100 case quic::NUM_FRAME_TYPES:
101 DCHECK(false) << "Cannot clone frame type: " << frame.type;
102 }
103 }
104 return new_frames;
105}
106
Michael Warres74ee3ce2017-10-09 15:26:37107} // namespace
108
Ryan Hamiltona1d1f4a2019-06-26 14:43:04109void QuicTestPacketMaker::DecoderStreamErrorDelegate::OnDecoderStreamError(
110 quic::QuicStringPiece error_message) {
111 LOG(FATAL) << error_message;
112}
113
114void QuicTestPacketMaker::EncoderStreamSenderDelegate::WriteStreamData(
115 quic::QuicStringPiece data) {
116 LOG(FATAL) << "data.length: " << data.length();
117}
118
Yixin Wang079ad542018-01-11 04:06:05119QuicTestPacketMaker::QuicTestPacketMaker(
Nick Harper23290b82019-05-02 00:02:56120 quic::ParsedQuicVersion version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52121 quic::QuicConnectionId connection_id,
122 quic::MockClock* clock,
Yixin Wang079ad542018-01-11 04:06:05123 const std::string& host,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52124 quic::Perspective perspective,
Yixin Wang079ad542018-01-11 04:06:05125 bool client_headers_include_h2_stream_dependency)
[email protected]1e960032013-12-20 19:00:20126 : version_(version),
[email protected]3aa9ca72014-02-27 19:39:43127 connection_id_(connection_id),
rtenneti4b06ae72014-08-26 03:43:43128 clock_(clock),
bncb07c05532015-05-14 19:07:20129 host_(host),
Ryan Hamilton0239aac2018-05-19 00:03:13130 spdy_request_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION),
131 spdy_response_framer_(spdy::SpdyFramer::ENABLE_COMPRESSION),
Ryan Hamilton9f2eac32019-06-27 03:15:54132 coalesce_http_frames_(false),
Ryan Hamiltone940bd12019-06-30 02:46:45133 save_packet_frames_(false),
Bence Békydec388b2019-08-08 04:28:57134 qpack_encoder_(&decoder_stream_error_delegate_),
Yixin Wang079ad542018-01-11 04:06:05135 perspective_(perspective),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52136 encryption_level_(quic::ENCRYPTION_FORWARD_SECURE),
Victor Vasilievf9693f02019-03-05 22:11:00137 long_header_type_(quic::INVALID_PACKET_TYPE),
Yixin Wang079ad542018-01-11 04:06:05138 client_headers_include_h2_stream_dependency_(
Yixin Wangb470bc882018-02-15 18:43:57139 client_headers_include_h2_stream_dependency &&
Nick Harper23290b82019-05-02 00:02:56140 version.transport_version >= quic::QUIC_VERSION_43) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:52141 DCHECK(!(perspective_ == quic::Perspective::IS_SERVER &&
Yixin Wang079ad542018-01-11 04:06:05142 client_headers_include_h2_stream_dependency_));
Bence Békydec388b2019-08-08 04:28:57143
144 qpack_encoder_.set_qpack_stream_sender_delegate(
145 &encoder_stream_sender_delegate_);
Yixin Wang079ad542018-01-11 04:06:05146}
[email protected]1e960032013-12-20 19:00:20147
Ryan Hamiltone940bd12019-06-30 02:46:45148QuicTestPacketMaker::~QuicTestPacketMaker() {
149 for (auto& kv : saved_frames_) {
150 quic::DeleteFrames(&(kv.second));
151 }
152}
[email protected]1e960032013-12-20 19:00:20153
bncb07c05532015-05-14 19:07:20154void QuicTestPacketMaker::set_hostname(const std::string& host) {
155 host_.assign(host);
156}
157
Ryan Hamilton8d9ee76e2018-05-29 23:52:52158std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23159QuicTestPacketMaker::MakeConnectivityProbingPacket(uint64_t num,
Zhongyi Shi879659422018-08-02 17:58:25160 bool include_version) {
David Schinazi83d21162019-06-21 18:07:42161 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03162
Nick Harper23290b82019-05-02 00:02:56163 quic::QuicFramer framer(quic::test::SupportedVersions(version_),
Victor Vasiliev49c25142019-03-08 04:40:47164 clock_->Now(), perspective_,
165 quic::kQuicDefaultConnectionIdLength);
Zhongyi Shi879659422018-08-02 17:58:25166 size_t max_plaintext_size =
167 framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize);
168 char buffer[quic::kDefaultMaxPacketSize];
Ryan Hamiltonaec5d4fc42018-10-24 17:12:48169 size_t length;
Nick Harper23290b82019-05-02 00:02:56170 if (version_.transport_version != quic::QUIC_VERSION_99) {
Michael Warres167db3e2019-03-01 21:38:03171 length = framer.BuildConnectivityProbingPacket(
David Schinazi83d21162019-06-21 18:07:42172 header_, buffer, max_plaintext_size, encryption_level_);
Ryan Hamiltonaec5d4fc42018-10-24 17:12:48173 } else if (perspective_ == quic::Perspective::IS_CLIENT) {
174 quic::test::MockRandom rand(0);
175 quic::QuicPathFrameBuffer payload;
David Schinazi83d21162019-06-21 18:07:42176 length = framer.BuildPaddedPathChallengePacket(header_, buffer,
177 max_plaintext_size, &payload,
178 &rand, encryption_level_);
Ryan Hamiltonaec5d4fc42018-10-24 17:12:48179 } else {
180 quic::test::MockRandom rand(0);
181 quic::QuicPathFrameBuffer payload;
182 rand.RandBytes(payload.data(), payload.size());
183 quic::QuicDeque<quic::QuicPathFrameBuffer> payloads{payload};
David Schinazi83d21162019-06-21 18:07:42184 length = framer.BuildPathResponsePacket(header_, buffer, max_plaintext_size,
Michael Warres167db3e2019-03-01 21:38:03185 payloads, true, encryption_level_);
Ryan Hamiltonaec5d4fc42018-10-24 17:12:48186 }
Zhongyi Shic4823bd2018-04-27 00:49:19187 size_t encrypted_size = framer.EncryptInPlace(
David Schinazi83d21162019-06-21 18:07:42188 quic::ENCRYPTION_INITIAL, header_.packet_number,
189 GetStartOfEncryptedData(framer.transport_version(), header_), length,
Zhongyi Shi879659422018-08-02 17:58:25190 quic::kDefaultMaxPacketSize, buffer);
191 EXPECT_EQ(quic::kDefaultMaxPacketSize, encrypted_size);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52192 quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
193 false);
Ryan Hamiltonb5afe582018-06-15 20:56:23194 return encrypted.Clone();
Zhongyi Shic4823bd2018-04-27 00:49:19195}
196
Ryan Hamilton8d9ee76e2018-05-29 23:52:52197std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakePingPacket(
Fan Yangac867502019-01-28 21:10:23198 uint64_t num,
jri7e636642016-01-14 06:57:08199 bool include_version) {
David Schinazi83d21162019-06-21 18:07:42200 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03201
Ryan Hamilton8d9ee76e2018-05-29 23:52:52202 quic::QuicPingFrame ping;
David Schinazi83d21162019-06-21 18:07:42203 return MakePacket(header_, quic::QuicFrame(ping));
jri7e636642016-01-14 06:57:08204}
205
Ryan Hamilton8d9ee76e2018-05-29 23:52:52206std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23207QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_num) {
Ryan Hamilton840358c2019-03-19 19:00:35208 SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
Zhongyi Shi5068bb02018-08-03 02:44:09209 InitializeHeader(packet_num, /*include_version=*/true);
Zhongyi Shi879659422018-08-02 17:58:25210
211 quic::CryptoHandshakeMessage message =
212 MockCryptoClientStream::GetDummyCHLOMessage();
Frank Kastenholz929883afb2018-09-07 20:56:37213 const quic::QuicData& data = message.GetSerialized();
Zhongyi Shi879659422018-08-02 17:58:25214
215 quic::QuicFrames frames;
Nick Harper158da41f2019-03-04 22:17:44216 quic::QuicCryptoFrame crypto_frame;
217 quic::test::SimpleDataProducer producer;
218 quic::QuicStreamFrameDataProducer* producer_p = nullptr;
Nick Harper23290b82019-05-02 00:02:56219 if (!QuicVersionUsesCryptoFrames(version_.transport_version)) {
220 quic::QuicStreamFrame frame(
221 quic::QuicUtils::GetCryptoStreamId(version_.transport_version),
222 /*fin=*/false, /*offset=*/0, data.AsStringPiece());
Nick Harper158da41f2019-03-04 22:17:44223 frames.push_back(quic::QuicFrame(frame));
224 } else {
225 crypto_frame =
Ryan Hamilton840358c2019-03-19 19:00:35226 quic::QuicCryptoFrame(quic::ENCRYPTION_INITIAL, 0, data.length());
227 producer.SaveCryptoData(quic::ENCRYPTION_INITIAL, 0, data.AsStringPiece());
Nick Harper158da41f2019-03-04 22:17:44228 frames.push_back(quic::QuicFrame(&crypto_frame));
229 producer_p = &producer;
230 }
Zhongyi Shi879659422018-08-02 17:58:25231 DVLOG(1) << "Adding frame: " << frames.back();
232 quic::QuicPaddingFrame padding;
233 frames.push_back(quic::QuicFrame(padding));
234 DVLOG(1) << "Adding frame: " << frames.back();
235
Nick Harper158da41f2019-03-04 22:17:44236 std::unique_ptr<quic::QuicReceivedPacket> packet =
237 MakeMultipleFramesPacket(header_, frames, producer_p);
238 return packet;
Zhongyi Shi879659422018-08-02 17:58:25239}
240
241std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23242QuicTestPacketMaker::MakeAckAndPingPacket(uint64_t num,
243 bool include_version,
244 uint64_t largest_received,
245 uint64_t smallest_received,
246 uint64_t least_unacked) {
David Schinazi83d21162019-06-21 18:07:42247 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03248
Ryan Hamilton8d9ee76e2018-05-29 23:52:52249 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
250 ack.ack_delay_time = quic::QuicTime::Delta::Zero();
Fan Yangac867502019-01-28 21:10:23251 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
252 ack.received_packet_times.push_back(
253 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
Fan Yang4cc86f1f2018-01-22 22:43:46254 }
255 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:23256 ack.packets.AddRange(quic::QuicPacketNumber(1),
257 quic::QuicPacketNumber(largest_received + 1));
Fan Yang4cc86f1f2018-01-22 22:43:46258 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:52259 quic::QuicFrames frames;
260 frames.push_back(quic::QuicFrame(&ack));
Zhongyi Shicbe75b32018-05-30 05:20:28261 DVLOG(1) << "Adding frame: " << frames.back();
Fan Yang4cc86f1f2018-01-22 22:43:46262
Ryan Hamilton8d9ee76e2018-05-29 23:52:52263 frames.push_back(quic::QuicFrame(quic::QuicPingFrame()));
Zhongyi Shicbe75b32018-05-30 05:20:28264 DVLOG(1) << "Adding frame: " << frames.back();
Fan Yang4cc86f1f2018-01-22 22:43:46265
David Schinazi83d21162019-06-21 18:07:42266 return MakeMultipleFramesPacket(header_, frames, nullptr);
Fan Yang4cc86f1f2018-01-22 22:43:46267}
268
Ryan Hamilton8d9ee76e2018-05-29 23:52:52269std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
Fan Yangac867502019-01-28 21:10:23270 uint64_t num,
[email protected]1e960032013-12-20 19:00:20271 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52272 quic::QuicStreamId stream_id,
273 quic::QuicRstStreamErrorCode error_code) {
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41274 return MakeRstPacket(num, include_version, stream_id, error_code,
Frank Kastenholz684ea412019-02-13 18:48:18275 /*include_stop_sending_if_v99=*/true);
xunjieli2608f9b2016-03-14 13:39:23276}
277
Ryan Hamilton8d9ee76e2018-05-29 23:52:52278std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeRstPacket(
Fan Yangac867502019-01-28 21:10:23279 uint64_t num,
xunjieli2608f9b2016-03-14 13:39:23280 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52281 quic::QuicStreamId stream_id,
282 quic::QuicRstStreamErrorCode error_code,
Frank Kastenholz684ea412019-02-13 18:48:18283 bool include_stop_sending_if_v99) {
David Schinazi83d21162019-06-21 18:07:42284 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03285
Frank Kastenholzbb4f76a2019-01-04 13:30:32286 quic::QuicFrames frames;
287
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41288 quic::QuicRstStreamFrame rst(1, stream_id, error_code,
289 stream_offsets_[stream_id]);
Frank Kastenholzbb4f76a2019-01-04 13:30:32290 frames.push_back(quic::QuicFrame(&rst));
291 DVLOG(1) << "Adding frame: " << frames.back();
292
293 // The STOP_SENDING frame must be outside of the if (version==99) so that it
294 // stays in scope until the packet is built.
295 quic::QuicStopSendingFrame stop(1, stream_id, error_code);
Nick Harper23290b82019-05-02 00:02:56296 if (include_stop_sending_if_v99 &&
297 version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholzbb4f76a2019-01-04 13:30:32298 frames.push_back(quic::QuicFrame(&stop));
299 DVLOG(1) << "Adding frame: " << frames.back();
300 }
David Schinazi83d21162019-06-21 18:07:42301 return MakeMultipleFramesPacket(header_, frames, nullptr);
[email protected]1e960032013-12-20 19:00:20302}
303
Ryan Hamilton8d9ee76e2018-05-29 23:52:52304std::unique_ptr<quic::QuicReceivedPacket>
David Schinazicc1bc592019-04-24 19:40:31305QuicTestPacketMaker::MakeStreamsBlockedPacket(
306 uint64_t num,
307 bool include_version,
308 quic::QuicStreamCount stream_count,
309 bool unidirectional) {
David Schinazi83d21162019-06-21 18:07:42310 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03311
David Schinazicc1bc592019-04-24 19:40:31312 quic::QuicStreamsBlockedFrame frame(1, stream_count, unidirectional);
Frank Kastenholz878763bf2018-11-28 19:14:48313 DVLOG(1) << "Adding frame: " << quic::QuicFrame(frame);
David Schinazi83d21162019-06-21 18:07:42314 return MakePacket(header_, quic::QuicFrame(frame));
Frank Kastenholz878763bf2018-11-28 19:14:48315}
316
317std::unique_ptr<quic::QuicReceivedPacket>
David Schinazicc1bc592019-04-24 19:40:31318QuicTestPacketMaker::MakeMaxStreamsPacket(uint64_t num,
319 bool include_version,
320 quic::QuicStreamCount stream_count,
321 bool unidirectional) {
David Schinazi83d21162019-06-21 18:07:42322 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03323
David Schinazicc1bc592019-04-24 19:40:31324 quic::QuicMaxStreamsFrame frame(1, stream_count, unidirectional);
Frank Kastenholz878763bf2018-11-28 19:14:48325 DVLOG(1) << "Adding frame: " << quic::QuicFrame(frame);
David Schinazi83d21162019-06-21 18:07:42326 return MakePacket(header_, quic::QuicFrame(frame));
Frank Kastenholz878763bf2018-11-28 19:14:48327}
328
329std::unique_ptr<quic::QuicReceivedPacket>
Fan Yang550c6282018-06-22 18:53:25330QuicTestPacketMaker::MakeRstAndRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23331 uint64_t num,
Fan Yang550c6282018-06-22 18:53:25332 bool include_version,
333 quic::QuicStreamId rst_stream_id,
334 quic::QuicRstStreamErrorCode rst_error_code,
335 quic::QuicStreamId stream_id,
336 bool fin,
337 spdy::SpdyPriority priority,
338 spdy::SpdyHeaderBlock headers,
339 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:02340 size_t* spdy_headers_frame_length) {
David Schinazi83d21162019-06-21 18:07:42341 InitializeHeader(num, include_version);
Fan Yang550c6282018-06-22 18:53:25342 quic::QuicRstStreamFrame rst_frame(1, rst_stream_id, rst_error_code, 0);
Fan Yang550c6282018-06-22 18:53:25343 quic::QuicFrames frames;
344 frames.push_back(quic::QuicFrame(&rst_frame));
345 DVLOG(1) << "Adding frame: " << frames.back();
Frank Kastenholzbb4f76a2019-01-04 13:30:32346
347 // The STOP_SENDING frame must be outside of the if (version==99) so that it
348 // stays in scope until the packet is built.
349 quic::QuicStopSendingFrame stop(1, rst_stream_id, rst_error_code);
Nick Harper23290b82019-05-02 00:02:56350 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholzbb4f76a2019-01-04 13:30:32351 frames.push_back(quic::QuicFrame(&stop));
352 DVLOG(1) << "Adding frame: " << frames.back();
353 }
Fan Yang550c6282018-06-22 18:53:25354
Ryan Hamiltona1d1f4a2019-06-26 14:43:04355 if (quic::VersionUsesQpack(version_.transport_version)) {
Ryan Hamiltona42582ef2019-08-23 04:09:36356 // Send SETTINGS frame(s) if they have not already been sent.
357 MaybeAddHttp3SettingsFrames(&frames);
Ryan Hamilton3cc2c152019-07-09 19:36:01358
Ryan Hamilton2a9f45a2019-08-22 18:28:38359 std::string priority_data = GenerateHttp3PriorityData(priority, stream_id);
Ryan Hamilton3cc2c152019-07-09 19:36:01360
Ryan Hamilton0564d0c2019-08-22 01:41:43361 frames.push_back(GenerateNextStreamFrame(2, false, priority_data));
Ryan Hamilton3cc2c152019-07-09 19:36:01362
363 // STREAM frames for HEADERS.
Ryan Hamiltona1d1f4a2019-06-26 14:43:04364 std::vector<std::string> data = QpackEncodeHeaders(
365 stream_id, std::move(headers), spdy_headers_frame_length);
Ryan Hamilton0564d0c2019-08-22 01:41:43366 for (const auto& frame : GenerateNextStreamFrames(stream_id, fin, data))
367 frames.push_back(frame);
Ryan Hamilton3cc2c152019-07-09 19:36:01368
Ryan Hamiltona1d1f4a2019-06-26 14:43:04369 InitializeHeader(num, include_version);
370 return MakeMultipleFramesPacket(header_, frames, nullptr);
371 }
372
373 spdy::SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
374 stream_id, fin, priority, std::move(headers), parent_stream_id);
375 if (spdy_headers_frame_length) {
376 *spdy_headers_frame_length = spdy_frame.size();
377 }
Ryan Hamilton0564d0c2019-08-22 01:41:43378 frames.push_back(GenerateNextStreamFrame(
Bence Béky7d168142019-08-06 17:10:23379 GetHeadersStreamId(), false,
Ryan Hamilton0564d0c2019-08-22 01:41:43380 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
Ryan Hamiltona1d1f4a2019-06-26 14:43:04381
382 InitializeHeader(num, include_version);
Nick Harper158da41f2019-03-04 22:17:44383 return MakeMultipleFramesPacket(header_, frames, nullptr);
Fan Yang550c6282018-06-22 18:53:25384}
385
386std::unique_ptr<quic::QuicReceivedPacket>
Ryan Hamilton8d9ee76e2018-05-29 23:52:52387QuicTestPacketMaker::MakeAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23388 uint64_t num,
[email protected]c5e1aca2014-01-30 04:03:04389 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52390 quic::QuicStreamId stream_id,
391 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23392 uint64_t largest_received,
393 uint64_t smallest_received,
394 uint64_t least_unacked,
[email protected]c5e1aca2014-01-30 04:03:04395 bool send_feedback) {
Yixin Wang0d2c6b7e12017-08-16 21:12:55396 return MakeAckAndRstPacket(num, include_version, stream_id, error_code,
397 largest_received, smallest_received, least_unacked,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41398 send_feedback,
Frank Kastenholz684ea412019-02-13 18:48:18399 /*include_stop_sending_if_v99=*/true);
Yixin Wang0d2c6b7e12017-08-16 21:12:55400}
401
Ryan Hamilton8d9ee76e2018-05-29 23:52:52402std::unique_ptr<quic::QuicReceivedPacket>
403QuicTestPacketMaker::MakeAckAndRstPacket(
Fan Yangac867502019-01-28 21:10:23404 uint64_t num,
Yixin Wang0d2c6b7e12017-08-16 21:12:55405 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52406 quic::QuicStreamId stream_id,
407 quic::QuicRstStreamErrorCode error_code,
Fan Yangac867502019-01-28 21:10:23408 uint64_t largest_received,
409 uint64_t smallest_received,
410 uint64_t least_unacked,
Yixin Wang0d2c6b7e12017-08-16 21:12:55411 bool send_feedback,
Frank Kastenholz684ea412019-02-13 18:48:18412 bool include_stop_sending_if_v99) {
David Schinazi83d21162019-06-21 18:07:42413 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03414
Ryan Hamilton8d9ee76e2018-05-29 23:52:52415 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
416 ack.ack_delay_time = quic::QuicTime::Delta::Zero();
Fan Yangac867502019-01-28 21:10:23417 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
418 ack.received_packet_times.push_back(
419 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
rtenneti4b06ae72014-08-26 03:43:43420 }
mpw94250b82016-11-19 18:13:30421 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:23422 ack.packets.AddRange(quic::QuicPacketNumber(1),
423 quic::QuicPacketNumber(largest_received + 1));
alyssar2adf3ac2016-05-03 17:12:58424 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:52425 quic::QuicFrames frames;
426 frames.push_back(quic::QuicFrame(&ack));
Zhongyi Shicbe75b32018-05-30 05:20:28427 DVLOG(1) << "Adding frame: " << frames.back();
[email protected]c5e1aca2014-01-30 04:03:04428
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41429 quic::QuicRstStreamFrame rst(1, stream_id, error_code,
430 stream_offsets_[stream_id]);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52431 frames.push_back(quic::QuicFrame(&rst));
Zhongyi Shicbe75b32018-05-30 05:20:28432 DVLOG(1) << "Adding frame: " << frames.back();
[email protected]c5e1aca2014-01-30 04:03:04433
Frank Kastenholzbb4f76a2019-01-04 13:30:32434 // The STOP_SENDING frame must be outside of the if (version==99) so that it
435 // stays in scope until the packet is built.
436 quic::QuicStopSendingFrame stop(1, stream_id, error_code);
Nick Harper23290b82019-05-02 00:02:56437 if (version_.transport_version == quic::QUIC_VERSION_99 &&
438 include_stop_sending_if_v99) {
Frank Kastenholzbb4f76a2019-01-04 13:30:32439 frames.push_back(quic::QuicFrame(&stop));
440 DVLOG(1) << "Adding frame: " << frames.back();
441 }
442
David Schinazi83d21162019-06-21 18:07:42443 return MakeMultipleFramesPacket(header_, frames, nullptr);
[email protected]c5e1aca2014-01-30 04:03:04444}
445
Ryan Hamilton8d9ee76e2018-05-29 23:52:52446std::unique_ptr<quic::QuicReceivedPacket>
Renjieba55fae2018-09-20 03:05:16447QuicTestPacketMaker::MakeRstAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23448 uint64_t num,
Renjieba55fae2018-09-20 03:05:16449 bool include_version,
450 quic::QuicStreamId stream_id,
451 quic::QuicRstStreamErrorCode error_code,
452 quic::QuicTime::Delta ack_delay_time,
Fan Yangac867502019-01-28 21:10:23453 uint64_t largest_received,
454 uint64_t smallest_received,
455 uint64_t least_unacked,
Renjieba55fae2018-09-20 03:05:16456 quic::QuicErrorCode quic_error,
457 const std::string& quic_error_details) {
David Schinazi83d21162019-06-21 18:07:42458 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03459
Renjieba55fae2018-09-20 03:05:16460 quic::QuicFrames frames;
461 quic::QuicRstStreamFrame rst(1, stream_id, error_code, 0);
462 frames.push_back(quic::QuicFrame(&rst));
463 DVLOG(1) << "Adding frame: " << frames.back();
464
Frank Kastenholzbb4f76a2019-01-04 13:30:32465 // The STOP_SENDING frame must be outside of the if (version==99) so that it
466 // stays in scope until the packet is built.
467 quic::QuicStopSendingFrame stop(
468 1, stream_id, static_cast<quic::QuicApplicationErrorCode>(error_code));
Nick Harper23290b82019-05-02 00:02:56469 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholzbb4f76a2019-01-04 13:30:32470 frames.push_back(quic::QuicFrame(&stop));
471 DVLOG(1) << "Adding frame: " << frames.back();
472 }
473
Renjieba55fae2018-09-20 03:05:16474 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
475 ack.ack_delay_time = ack_delay_time;
Fan Yangac867502019-01-28 21:10:23476 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
477 ack.received_packet_times.push_back(
478 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
Renjieba55fae2018-09-20 03:05:16479 }
480 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:23481 ack.packets.AddRange(quic::QuicPacketNumber(1),
482 quic::QuicPacketNumber(largest_received + 1));
Renjieba55fae2018-09-20 03:05:16483 }
484 frames.push_back(quic::QuicFrame(&ack));
485 DVLOG(1) << "Adding frame: " << frames.back();
Renjieba55fae2018-09-20 03:05:16486
Nick Harper33457ed052019-09-10 04:18:28487 quic::QuicConnectionCloseFrame close(version_.transport_version, quic_error,
488 quic_error_details,
489 /*transport_close_frame_type=*/0);
Renjieba55fae2018-09-20 03:05:16490
491 frames.push_back(quic::QuicFrame(&close));
492 DVLOG(1) << "Adding frame: " << frames.back();
493
David Schinazi83d21162019-06-21 18:07:42494 return MakeMultipleFramesPacket(header_, frames, nullptr);
Renjieba55fae2018-09-20 03:05:16495}
496
497std::unique_ptr<quic::QuicReceivedPacket>
zhongyica364fbb2015-12-12 03:39:12498QuicTestPacketMaker::MakeAckAndConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23499 uint64_t num,
zhongyica364fbb2015-12-12 03:39:12500 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52501 quic::QuicTime::Delta ack_delay_time,
Fan Yangac867502019-01-28 21:10:23502 uint64_t largest_received,
503 uint64_t smallest_received,
504 uint64_t least_unacked,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52505 quic::QuicErrorCode quic_error,
Renjie Tangff0d6372019-08-30 22:03:29506 const std::string& quic_error_details,
507 uint64_t frame_type) {
David Schinazi83d21162019-06-21 18:07:42508 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03509
Ryan Hamilton8d9ee76e2018-05-29 23:52:52510 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
rchcaec4242016-01-22 20:49:52511 ack.ack_delay_time = ack_delay_time;
Fan Yangac867502019-01-28 21:10:23512 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
513 ack.received_packet_times.push_back(
514 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
zhongyica364fbb2015-12-12 03:39:12515 }
mpw94250b82016-11-19 18:13:30516 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:23517 ack.packets.AddRange(quic::QuicPacketNumber(1),
518 quic::QuicPacketNumber(largest_received + 1));
alyssar2adf3ac2016-05-03 17:12:58519 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:52520 quic::QuicFrames frames;
521 frames.push_back(quic::QuicFrame(&ack));
Zhongyi Shicbe75b32018-05-30 05:20:28522 DVLOG(1) << "Adding frame: " << frames.back();
zhongyica364fbb2015-12-12 03:39:12523
Nick Harper33457ed052019-09-10 04:18:28524 quic::QuicConnectionCloseFrame close(version_.transport_version, quic_error,
525 quic_error_details, frame_type);
zhongyica364fbb2015-12-12 03:39:12526
Ryan Hamilton8d9ee76e2018-05-29 23:52:52527 frames.push_back(quic::QuicFrame(&close));
Zhongyi Shicbe75b32018-05-30 05:20:28528 DVLOG(1) << "Adding frame: " << frames.back();
zhongyica364fbb2015-12-12 03:39:12529
David Schinazi83d21162019-06-21 18:07:42530 return MakeMultipleFramesPacket(header_, frames, nullptr);
zhongyica364fbb2015-12-12 03:39:12531}
532
Ryan Hamilton8d9ee76e2018-05-29 23:52:52533std::unique_ptr<quic::QuicReceivedPacket>
Bin Wu5311aca2018-01-22 01:19:03534QuicTestPacketMaker::MakeConnectionClosePacket(
Fan Yangac867502019-01-28 21:10:23535 uint64_t num,
Bin Wu5311aca2018-01-22 01:19:03536 bool include_version,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52537 quic::QuicErrorCode quic_error,
Bin Wu5311aca2018-01-22 01:19:03538 const std::string& quic_error_details) {
David Schinazi83d21162019-06-21 18:07:42539 InitializeHeader(num, include_version);
Michael Warres167db3e2019-03-01 21:38:03540
Nick Harper33457ed052019-09-10 04:18:28541 quic::QuicConnectionCloseFrame close(version_.transport_version, quic_error,
542 quic_error_details,
543 /*transport_close_frame_type=*/0);
Zhongyi Shica576df2019-04-12 17:43:40544
David Schinazi83d21162019-06-21 18:07:42545 return MakePacket(header_, quic::QuicFrame(&close));
[email protected]1e960032013-12-20 19:00:20546}
547
Ryan Hamilton8d9ee76e2018-05-29 23:52:52548std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeGoAwayPacket(
Fan Yangac867502019-01-28 21:10:23549 uint64_t num,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52550 quic::QuicErrorCode error_code,
zhongyi6b5a3892016-03-12 04:46:20551 std::string reason_phrase) {
David Schinazi83d21162019-06-21 18:07:42552 InitializeHeader(num, /*include_version=*/false);
Michael Warres167db3e2019-03-01 21:38:03553
Ryan Hamilton8d9ee76e2018-05-29 23:52:52554 quic::QuicGoAwayFrame goaway;
zhongyi6b5a3892016-03-12 04:46:20555 goaway.error_code = error_code;
556 goaway.last_good_stream_id = 0;
557 goaway.reason_phrase = reason_phrase;
David Schinazi83d21162019-06-21 18:07:42558 return MakePacket(header_, quic::QuicFrame(&goaway));
zhongyi6b5a3892016-03-12 04:46:20559}
560
Ryan Hamilton8d9ee76e2018-05-29 23:52:52561std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
Fan Yangac867502019-01-28 21:10:23562 uint64_t packet_number,
563 uint64_t largest_received,
564 uint64_t smallest_received,
565 uint64_t least_unacked,
[email protected]1e960032013-12-20 19:00:20566 bool send_feedback) {
Zhongyi Shif5cc30392018-05-30 18:25:15567 return MakeAckPacket(packet_number, 1, largest_received, smallest_received,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52568 least_unacked, send_feedback,
569 quic::QuicTime::Delta::Zero());
zhongyi32569c62016-01-08 02:54:30570}
571
Ryan Hamilton8d9ee76e2018-05-29 23:52:52572std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
Fan Yangac867502019-01-28 21:10:23573 uint64_t packet_number,
574 uint64_t first_received,
575 uint64_t largest_received,
576 uint64_t smallest_received,
577 uint64_t least_unacked,
Zhongyi Shif5cc30392018-05-30 18:25:15578 bool send_feedback) {
579 return MakeAckPacket(packet_number, first_received, largest_received,
580 smallest_received, least_unacked, send_feedback,
581 quic::QuicTime::Delta::Zero());
582}
583
584std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
Fan Yangac867502019-01-28 21:10:23585 uint64_t packet_number,
586 uint64_t largest_received,
587 uint64_t smallest_received,
588 uint64_t least_unacked,
Zhongyi Shif5cc30392018-05-30 18:25:15589 bool send_feedback,
590 quic::QuicTime::Delta ack_delay_time) {
591 return MakeAckPacket(packet_number, 1, largest_received, smallest_received,
592 least_unacked, send_feedback, ack_delay_time);
593}
594
595std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeAckPacket(
Fan Yangac867502019-01-28 21:10:23596 uint64_t packet_number,
597 uint64_t first_received,
598 uint64_t largest_received,
599 uint64_t smallest_received,
600 uint64_t least_unacked,
rch9ecde09b2017-04-08 00:18:23601 bool send_feedback,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52602 quic::QuicTime::Delta ack_delay_time) {
David Schinazi83d21162019-06-21 18:07:42603 InitializeHeader(packet_number, /*include_version=*/false);
Michael Warres167db3e2019-03-01 21:38:03604
Ryan Hamilton8d9ee76e2018-05-29 23:52:52605 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
rch9ecde09b2017-04-08 00:18:23606 ack.ack_delay_time = ack_delay_time;
Fan Yangac867502019-01-28 21:10:23607 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
608 ack.received_packet_times.push_back(
609 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
rtenneti4b06ae72014-08-26 03:43:43610 }
mpw94250b82016-11-19 18:13:30611 if (largest_received > 0) {
Zhongyi Shif5cc30392018-05-30 18:25:15612 DCHECK_GE(largest_received, first_received);
Fan Yangac867502019-01-28 21:10:23613 ack.packets.AddRange(quic::QuicPacketNumber(first_received),
614 quic::QuicPacketNumber(largest_received + 1));
alyssar2adf3ac2016-05-03 17:12:58615 }
Nick Harper23290b82019-05-02 00:02:56616 quic::QuicFramer framer(quic::test::SupportedVersions(version_),
Victor Vasiliev49c25142019-03-08 04:40:47617 clock_->Now(), perspective_,
618 quic::kQuicDefaultConnectionIdLength);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52619 quic::QuicFrames frames;
620 quic::QuicFrame ack_frame(&ack);
ckrasic769733c2016-06-30 00:42:13621 frames.push_back(ack_frame);
Zhongyi Shicbe75b32018-05-30 05:20:28622 DVLOG(1) << "Adding frame: " << frames.back();
[email protected]93dd91f2014-02-27 00:09:03623
Nick Harperb16c354b2019-05-07 19:30:43624 size_t max_plaintext_size =
625 framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize);
626 size_t ack_frame_length = framer.GetSerializedFrameLength(
627 ack_frame, max_plaintext_size, /*first_frame*/ true, /*last_frame*/ false,
David Schinazi83d21162019-06-21 18:07:42628 header_.packet_number_length);
Nick Harperb16c354b2019-05-07 19:30:43629 const size_t min_plaintext_size = 7;
630 if (version_.HasHeaderProtection() && ack_frame_length < min_plaintext_size) {
631 size_t padding_length = min_plaintext_size - ack_frame_length;
632 frames.push_back(quic::QuicFrame(quic::QuicPaddingFrame(padding_length)));
633 }
634
Ryan Hamilton8d9ee76e2018-05-29 23:52:52635 std::unique_ptr<quic::QuicPacket> packet(
David Schinazi83d21162019-06-21 18:07:42636 quic::test::BuildUnsizedDataPacket(&framer, header_, frames));
Zhongyi Shica576df2019-04-12 17:43:40637 char buffer[quic::kMaxOutgoingPacketSize];
Ryan Hamilton8d9ee76e2018-05-29 23:52:52638 size_t encrypted_size =
David Schinazi83d21162019-06-21 18:07:42639 framer.EncryptPayload(quic::ENCRYPTION_INITIAL, header_.packet_number,
Zhongyi Shica576df2019-04-12 17:43:40640 *packet, buffer, quic::kMaxOutgoingPacketSize);
rch99b644c2015-11-04 05:25:28641 EXPECT_NE(0u, encrypted_size);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52642 quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
643 false);
Ryan Hamiltonb5afe582018-06-15 20:56:23644 return encrypted.Clone();
[email protected]1e960032013-12-20 19:00:20645}
646
Ryan Hamilton8d9ee76e2018-05-29 23:52:52647std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakeDataPacket(
Fan Yangac867502019-01-28 21:10:23648 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52649 quic::QuicStreamId stream_id,
[email protected]1e960032013-12-20 19:00:20650 bool should_include_version,
651 bool fin,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52652 quic::QuicStringPiece data) {
rtennetia004d332015-08-28 06:44:57653 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton0564d0c2019-08-22 01:41:43654 return MakePacket(header_, GenerateNextStreamFrame(stream_id, fin, data));
[email protected]1e960032013-12-20 19:00:20655}
656
Ryan Hamilton8d9ee76e2018-05-29 23:52:52657std::unique_ptr<quic::QuicReceivedPacket>
xunjieli07a42ce2016-04-26 20:05:31658QuicTestPacketMaker::MakeMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23659 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52660 quic::QuicStreamId stream_id,
xunjieli07a42ce2016-04-26 20:05:31661 bool should_include_version,
662 bool fin,
xunjieli07a42ce2016-04-26 20:05:31663 const std::vector<std::string>& data_writes) {
664 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52665 quic::QuicFrames data_frames;
xunjieli07a42ce2016-04-26 20:05:31666 for (size_t i = 0; i < data_writes.size(); ++i) {
667 bool is_fin = fin && (i == data_writes.size() - 1);
Ryan Hamilton0564d0c2019-08-22 01:41:43668 data_frames.push_back(
Ryan Hamilton7505eb92019-06-08 00:22:17669 GenerateNextStreamFrame(stream_id, is_fin, data_writes[i]));
xunjieli07a42ce2016-04-26 20:05:31670 }
Nick Harper158da41f2019-03-04 22:17:44671 return MakeMultipleFramesPacket(header_, data_frames, nullptr);
xunjieli07a42ce2016-04-26 20:05:31672}
673
Ryan Hamilton8d9ee76e2018-05-29 23:52:52674std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23675QuicTestPacketMaker::MakeAckAndDataPacket(uint64_t packet_number,
676 bool include_version,
677 quic::QuicStreamId stream_id,
678 uint64_t largest_received,
679 uint64_t smallest_received,
680 uint64_t least_unacked,
681 bool fin,
Fan Yangac867502019-01-28 21:10:23682 quic::QuicStringPiece data) {
jri7e636642016-01-14 06:57:08683 InitializeHeader(packet_number, include_version);
684
Ryan Hamilton8d9ee76e2018-05-29 23:52:52685 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
686 ack.ack_delay_time = quic::QuicTime::Delta::Zero();
Fan Yangac867502019-01-28 21:10:23687 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
688 ack.received_packet_times.push_back(
689 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
jri7e636642016-01-14 06:57:08690 }
mpw94250b82016-11-19 18:13:30691 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:23692 ack.packets.AddRange(quic::QuicPacketNumber(1),
693 quic::QuicPacketNumber(largest_received + 1));
alyssar2adf3ac2016-05-03 17:12:58694 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:52695 quic::QuicFrames frames;
696 frames.push_back(quic::QuicFrame(&ack));
Zhongyi Shicbe75b32018-05-30 05:20:28697 DVLOG(1) << "Adding frame: " << frames.back();
jri7e636642016-01-14 06:57:08698
Ryan Hamilton0564d0c2019-08-22 01:41:43699 frames.push_back(GenerateNextStreamFrame(stream_id, fin, data));
jri7e636642016-01-14 06:57:08700
Nick Harper158da41f2019-03-04 22:17:44701 return MakeMultipleFramesPacket(header_, frames, nullptr);
jri7e636642016-01-14 06:57:08702}
703
Ryan Hamilton8d9ee76e2018-05-29 23:52:52704std::unique_ptr<quic::QuicReceivedPacket>
Renjief49758b2019-01-11 23:32:41705QuicTestPacketMaker::MakeAckAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23706 uint64_t packet_number,
Renjief49758b2019-01-11 23:32:41707 bool include_version,
708 quic::QuicStreamId stream_id,
Fan Yangac867502019-01-28 21:10:23709 uint64_t largest_received,
710 uint64_t smallest_received,
711 uint64_t least_unacked,
Renjief49758b2019-01-11 23:32:41712 bool fin,
Renjief49758b2019-01-11 23:32:41713 const std::vector<std::string>& data_writes) {
714 InitializeHeader(packet_number, include_version);
715
716 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
717 ack.ack_delay_time = quic::QuicTime::Delta::Zero();
Fan Yangac867502019-01-28 21:10:23718 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
719 ack.received_packet_times.push_back(
720 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
Renjief49758b2019-01-11 23:32:41721 }
722 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:23723 ack.packets.AddRange(quic::QuicPacketNumber(1),
724 quic::QuicPacketNumber(largest_received + 1));
Renjief49758b2019-01-11 23:32:41725 }
726 quic::QuicFrames frames;
727 frames.push_back(quic::QuicFrame(&ack));
728 DVLOG(1) << "Adding frame: " << frames.back();
729
Renjief49758b2019-01-11 23:32:41730 for (size_t i = 0; i < data_writes.size(); ++i) {
731 bool is_fin = fin && (i == data_writes.size() - 1);
Ryan Hamilton0564d0c2019-08-22 01:41:43732 frames.push_back(GenerateNextStreamFrame(
Ryan Hamilton7505eb92019-06-08 00:22:17733 stream_id, is_fin, quic::QuicStringPiece(data_writes[i])));
Renjief49758b2019-01-11 23:32:41734 }
Nick Harper158da41f2019-03-04 22:17:44735 return MakeMultipleFramesPacket(header_, frames, nullptr);
Renjief49758b2019-01-11 23:32:41736}
737
738std::unique_ptr<quic::QuicReceivedPacket>
xunjieli07a42ce2016-04-26 20:05:31739QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
Fan Yangac867502019-01-28 21:10:23740 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52741 quic::QuicStreamId stream_id,
xunjieli07a42ce2016-04-26 20:05:31742 bool should_include_version,
743 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13744 spdy::SpdyPriority priority,
745 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52746 quic::QuicStreamId parent_stream_id,
xunjieli07a42ce2016-04-26 20:05:31747 size_t* spdy_headers_frame_length,
748 const std::vector<std::string>& data_writes) {
749 InitializeHeader(packet_number, should_include_version);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04750 if (quic::VersionUsesQpack(version_.transport_version)) {
Ryan Hamilton3cc2c152019-07-09 19:36:01751 quic::QuicFrames frames;
Ryan Hamiltona42582ef2019-08-23 04:09:36752
753 // Send SETTINGS frame(s) if they have not already been sent.
754 MaybeAddHttp3SettingsFrames(&frames);
Ryan Hamilton3cc2c152019-07-09 19:36:01755
Ryan Hamilton2a9f45a2019-08-22 18:28:38756 std::string priority_data = GenerateHttp3PriorityData(priority, stream_id);
Ryan Hamilton0564d0c2019-08-22 01:41:43757 frames.push_back(GenerateNextStreamFrame(2, false, priority_data));
Ryan Hamilton3cc2c152019-07-09 19:36:01758
Ryan Hamiltona1d1f4a2019-06-26 14:43:04759 // STREAM frames for HEADERS.
760 std::vector<std::string> data = QpackEncodeHeaders(
761 stream_id, std::move(headers), spdy_headers_frame_length);
Ryan Hamilton0564d0c2019-08-22 01:41:43762
763 for (const auto& frame : GenerateNextStreamFrames(stream_id, false, data))
764 frames.push_back(frame);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04765
766 // STREAM frames for DATA.
767 for (size_t i = 0; i < data_writes.size(); ++i) {
768 bool is_fin = fin && (i == data_writes.size() - 1);
Ryan Hamilton0564d0c2019-08-22 01:41:43769 frames.push_back(GenerateNextStreamFrame(
Ryan Hamiltona1d1f4a2019-06-26 14:43:04770 stream_id, is_fin, quic::QuicStringPiece(data_writes[i])));
771 }
772
Ryan Hamiltona1d1f4a2019-06-26 14:43:04773 return MakeMultipleFramesPacket(header_, frames, nullptr);
774 }
775
Ryan Hamilton0239aac2018-05-19 00:03:13776 spdy::SpdySerializedFrame spdy_frame =
Yixin Wange78346d2018-03-02 20:58:33777 MakeSpdyHeadersFrame(stream_id, fin && data_writes.empty(), priority,
778 std::move(headers), parent_stream_id);
yasongc90cb532016-11-27 02:33:29779
xunjieli07a42ce2016-04-26 20:05:31780 if (spdy_headers_frame_length) {
781 *spdy_headers_frame_length = spdy_frame.size();
782 }
Ryan Hamilton7505eb92019-06-08 00:22:17783 quic::QuicFrames frames;
Ryan Hamilton0564d0c2019-08-22 01:41:43784 frames.push_back(GenerateNextStreamFrame(
785 GetHeadersStreamId(), false,
786 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
xunjieli07a42ce2016-04-26 20:05:31787
Ryan Hamilton8d9ee76e2018-05-29 23:52:52788 // quic::QuicFrame takes a raw pointer. Use a std::vector here so we keep
xunjieli07a42ce2016-04-26 20:05:31789 // StreamFrames alive until MakeMultipleFramesPacket is done.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52790 std::vector<std::unique_ptr<quic::QuicStreamFrame>> stream_frames;
xunjieli07a42ce2016-04-26 20:05:31791 for (size_t i = 0; i < data_writes.size(); ++i) {
792 bool is_fin = fin && (i == data_writes.size() - 1);
Ryan Hamilton0564d0c2019-08-22 01:41:43793 frames.push_back(GenerateNextStreamFrame(
Ryan Hamilton7505eb92019-06-08 00:22:17794 stream_id, is_fin, quic::QuicStringPiece(data_writes[i])));
xunjieli07a42ce2016-04-26 20:05:31795 }
Nick Harper158da41f2019-03-04 22:17:44796 return MakeMultipleFramesPacket(header_, frames, nullptr);
xunjieli07a42ce2016-04-26 20:05:31797}
798
Ryan Hamilton8d9ee76e2018-05-29 23:52:52799std::unique_ptr<quic::QuicReceivedPacket>
danakjad1777e2016-04-16 00:56:42800QuicTestPacketMaker::MakeRequestHeadersPacket(
Fan Yangac867502019-01-28 21:10:23801 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52802 quic::QuicStreamId stream_id,
[email protected]1e960032013-12-20 19:00:20803 bool should_include_version,
804 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13805 spdy::SpdyPriority priority,
806 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52807 quic::QuicStreamId parent_stream_id,
sclittlec4dc1a32015-09-24 00:15:45808 size_t* spdy_headers_frame_length) {
rtennetia004d332015-08-28 06:44:57809 InitializeHeader(packet_number, should_include_version);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04810
811 if (quic::VersionUsesQpack(version_.transport_version)) {
Ryan Hamilton3cc2c152019-07-09 19:36:01812 quic::QuicFrames frames;
Ryan Hamiltona42582ef2019-08-23 04:09:36813
814 // Send SETTINGS frame(s) if they have not already been sent.
815 MaybeAddHttp3SettingsFrames(&frames);
Ryan Hamilton3cc2c152019-07-09 19:36:01816
Ryan Hamilton2a9f45a2019-08-22 18:28:38817 std::string priority_data = GenerateHttp3PriorityData(priority, stream_id);
Ryan Hamilton0564d0c2019-08-22 01:41:43818 frames.push_back(GenerateNextStreamFrame(2, false, priority_data));
Ryan Hamilton3cc2c152019-07-09 19:36:01819
Ryan Hamiltona1d1f4a2019-06-26 14:43:04820 std::vector<std::string> data = QpackEncodeHeaders(
821 stream_id, std::move(headers), spdy_headers_frame_length);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04822
Ryan Hamilton0564d0c2019-08-22 01:41:43823 for (const auto& frame : GenerateNextStreamFrames(stream_id, fin, data))
824 frames.push_back(frame);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04825 return MakeMultipleFramesPacket(header_, frames, nullptr);
826 }
827
Ryan Hamilton0239aac2018-05-19 00:03:13828 spdy::SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
Yixin Wang7a3f1b8d2018-01-17 21:40:48829 stream_id, fin, priority, std::move(headers), parent_stream_id);
yasongc90cb532016-11-27 02:33:29830
rchf406bd32017-04-03 19:10:51831 if (spdy_headers_frame_length)
bncb03b1092016-04-06 11:19:55832 *spdy_headers_frame_length = spdy_frame.size();
rchf406bd32017-04-03 19:10:51833
Ryan Hamilton0564d0c2019-08-22 01:41:43834 return MakePacket(header_, GenerateNextStreamFrame(
835 GetHeadersStreamId(), false,
836 quic::QuicStringPiece(spdy_frame.data(),
837 spdy_frame.size())));
[email protected]1e960032013-12-20 19:00:20838}
839
Ryan Hamilton8d9ee76e2018-05-29 23:52:52840std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:25841QuicTestPacketMaker::MakeRequestHeadersAndRstPacket(
Fan Yangac867502019-01-28 21:10:23842 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52843 quic::QuicStreamId stream_id,
Yixin Wange7ecc472018-03-06 19:00:25844 bool should_include_version,
845 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13846 spdy::SpdyPriority priority,
847 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52848 quic::QuicStreamId parent_stream_id,
Yixin Wange7ecc472018-03-06 19:00:25849 size_t* spdy_headers_frame_length,
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41850 quic::QuicRstStreamErrorCode error_code) {
Ryan Hamiltona1d1f4a2019-06-26 14:43:04851 if (quic::VersionUsesQpack(version_.transport_version)) {
Ryan Hamilton3cc2c152019-07-09 19:36:01852 quic::QuicFrames frames;
Ryan Hamiltonceb429bc2019-08-23 03:26:39853
Ryan Hamiltona42582ef2019-08-23 04:09:36854 // Send SETTINGS frame(s) if they have not already been sent.
855 MaybeAddHttp3SettingsFrames(&frames);
Ryan Hamilton3cc2c152019-07-09 19:36:01856
Ryan Hamilton2a9f45a2019-08-22 18:28:38857 std::string priority_data = GenerateHttp3PriorityData(priority, stream_id);
Ryan Hamilton0564d0c2019-08-22 01:41:43858 frames.push_back(GenerateNextStreamFrame(2, false, priority_data));
Ryan Hamilton3cc2c152019-07-09 19:36:01859
Ryan Hamiltona1d1f4a2019-06-26 14:43:04860 std::vector<std::string> data = QpackEncodeHeaders(
861 stream_id, std::move(headers), spdy_headers_frame_length);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04862
Ryan Hamilton0564d0c2019-08-22 01:41:43863 for (const auto& frame : GenerateNextStreamFrames(stream_id, fin, data))
864 frames.push_back(frame);
Ryan Hamiltona1d1f4a2019-06-26 14:43:04865
866 quic::QuicRstStreamFrame rst_frame(1, stream_id, error_code,
867 stream_offsets_[stream_id]);
868 frames.push_back(quic::QuicFrame(&rst_frame));
869 DVLOG(1) << "Adding frame: " << frames.back();
870
871 quic::QuicStopSendingFrame stop(1, stream_id, error_code);
872 frames.push_back(quic::QuicFrame(&stop));
873 DVLOG(1) << "Adding frame: " << frames.back();
874 InitializeHeader(packet_number, should_include_version);
875 return MakeMultipleFramesPacket(header_, frames, nullptr);
876 }
877
Ryan Hamilton0239aac2018-05-19 00:03:13878 spdy::SpdySerializedFrame spdy_frame = MakeSpdyHeadersFrame(
Yixin Wange7ecc472018-03-06 19:00:25879 stream_id, fin, priority, std::move(headers), parent_stream_id);
880 if (spdy_headers_frame_length) {
881 *spdy_headers_frame_length = spdy_frame.size();
882 }
Ryan Hamilton0564d0c2019-08-22 01:41:43883 quic::QuicFrames frames;
884 frames.push_back(GenerateNextStreamFrame(
Bence Béky7d168142019-08-06 17:10:23885 GetHeadersStreamId(), false,
Ryan Hamilton0564d0c2019-08-22 01:41:43886 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size())));
887 DVLOG(1) << "Adding frame: " << frames.back();
Yixin Wange7ecc472018-03-06 19:00:25888
Ryan Hamiltonb5d4c5a2019-06-21 22:08:41889 quic::QuicRstStreamFrame rst_frame(1, stream_id, error_code,
890 stream_offsets_[stream_id]);
Yixin Wange7ecc472018-03-06 19:00:25891
Ryan Hamilton8d9ee76e2018-05-29 23:52:52892 frames.push_back(quic::QuicFrame(&rst_frame));
Yixin Wange7ecc472018-03-06 19:00:25893 DVLOG(1) << "Adding frame: " << frames.back();
894
Frank Kastenholzbb4f76a2019-01-04 13:30:32895 // The STOP_SENDING frame must be outside of the if (version==99) so that it
896 // stays in scope until the packet is built.
897 quic::QuicStopSendingFrame stop(1, stream_id, error_code);
Nick Harper23290b82019-05-02 00:02:56898 if (version_.transport_version == quic::QUIC_VERSION_99) {
Frank Kastenholzbb4f76a2019-01-04 13:30:32899 frames.push_back(quic::QuicFrame(&stop));
900 DVLOG(1) << "Adding frame: " << frames.back();
901 }
902
Yixin Wange7ecc472018-03-06 19:00:25903 InitializeHeader(packet_number, should_include_version);
Nick Harper158da41f2019-03-04 22:17:44904 return MakeMultipleFramesPacket(header_, frames, nullptr);
Yixin Wange7ecc472018-03-06 19:00:25905}
906
Ryan Hamilton0239aac2018-05-19 00:03:13907spdy::SpdySerializedFrame QuicTestPacketMaker::MakeSpdyHeadersFrame(
Ryan Hamilton8d9ee76e2018-05-29 23:52:52908 quic::QuicStreamId stream_id,
Yixin Wang079ad542018-01-11 04:06:05909 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13910 spdy::SpdyPriority priority,
911 spdy::SpdyHeaderBlock headers,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52912 quic::QuicStreamId parent_stream_id) {
Ryan Hamilton0239aac2018-05-19 00:03:13913 spdy::SpdyHeadersIR headers_frame(stream_id, std::move(headers));
Yixin Wang079ad542018-01-11 04:06:05914 headers_frame.set_fin(fin);
Ryan Hamilton0239aac2018-05-19 00:03:13915 headers_frame.set_weight(spdy::Spdy3PriorityToHttp2Weight(priority));
Yixin Wang079ad542018-01-11 04:06:05916 headers_frame.set_has_priority(true);
917
918 if (client_headers_include_h2_stream_dependency_) {
Yixin Wang079ad542018-01-11 04:06:05919 headers_frame.set_parent_stream_id(parent_stream_id);
920 headers_frame.set_exclusive(true);
921 } else {
922 headers_frame.set_parent_stream_id(0);
923 headers_frame.set_exclusive(false);
924 }
925
926 return spdy_request_framer_.SerializeFrame(headers_frame);
927}
928
Ryan Hamilton8d9ee76e2018-05-29 23:52:52929std::unique_ptr<quic::QuicReceivedPacket>
930QuicTestPacketMaker::MakePushPromisePacket(
Fan Yangac867502019-01-28 21:10:23931 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52932 quic::QuicStreamId stream_id,
933 quic::QuicStreamId promised_stream_id,
ckrasic769733c2016-06-30 00:42:13934 bool should_include_version,
935 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13936 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02937 size_t* spdy_headers_frame_length) {
Fan Yang2330d182019-08-05 14:50:50938 if (quic::VersionUsesQpack(version_.transport_version)) {
939 std::string encoded_headers =
Nick Harper057264a82019-09-12 23:33:49940 qpack_encoder_.EncodeHeaderList(stream_id, headers, nullptr);
Fan Yang2330d182019-08-05 14:50:50941 quic::QuicFrames frames;
942 quic::PushPromiseFrame frame;
943 frame.push_id = promised_stream_id;
944 frame.headers = encoded_headers;
945 std::unique_ptr<char[]> buffer;
946 quic::QuicByteCount frame_length =
947 http_encoder_.SerializePushPromiseFrameWithOnlyPushId(frame, &buffer);
948 std::string push_promise_data(buffer.get(), frame_length);
Ryan Hamilton0564d0c2019-08-22 01:41:43949 frames.push_back(
950 GenerateNextStreamFrame(stream_id, false, push_promise_data));
951 frames.push_back(
952 GenerateNextStreamFrame(stream_id, false, encoded_headers));
Fan Yang2330d182019-08-05 14:50:50953 InitializeHeader(packet_number, should_include_version);
954 return MakeMultipleFramesPacket(header_, frames, nullptr);
955 }
ckrasic769733c2016-06-30 00:42:13956 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton0239aac2018-05-19 00:03:13957 spdy::SpdySerializedFrame spdy_frame;
958 spdy::SpdyPushPromiseIR promise_frame(stream_id, promised_stream_id,
959 std::move(headers));
ckrasic769733c2016-06-30 00:42:13960 promise_frame.set_fin(fin);
961 spdy_frame = spdy_request_framer_.SerializeFrame(promise_frame);
962 if (spdy_headers_frame_length) {
963 *spdy_headers_frame_length = spdy_frame.size();
964 }
Ryan Hamilton0564d0c2019-08-22 01:41:43965 return MakePacket(header_, GenerateNextStreamFrame(
966 GetHeadersStreamId(), false,
967 quic::QuicStringPiece(spdy_frame.data(),
968 spdy_frame.size())));
ckrasic769733c2016-06-30 00:42:13969}
970
Ryan Hamilton8d9ee76e2018-05-29 23:52:52971std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:23972QuicTestPacketMaker::MakeForceHolDataPacket(uint64_t packet_number,
973 quic::QuicStreamId stream_id,
974 bool should_include_version,
975 bool fin,
976 quic::QuicStreamOffset* offset,
977 quic::QuicStringPiece data) {
Ryan Hamilton0239aac2018-05-19 00:03:13978 spdy::SpdyDataIR spdy_data(stream_id, data);
ckrasicda193a82016-07-09 00:39:36979 spdy_data.set_fin(fin);
Ryan Hamilton0239aac2018-05-19 00:03:13980 spdy::SpdySerializedFrame spdy_frame(
ckrasicda193a82016-07-09 00:39:36981 spdy_request_framer_.SerializeFrame(spdy_data));
982 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton8d9ee76e2018-05-29 23:52:52983 quic::QuicStreamFrame quic_frame(
Bence Béky7d168142019-08-06 17:10:23984 GetHeadersStreamId(), false, *offset,
985 quic::QuicStringPiece(spdy_frame.data(), spdy_frame.size()));
ckrasicda193a82016-07-09 00:39:36986 *offset += spdy_frame.size();
Zhongyi Shi7b4f22b2018-08-23 17:22:26987 return MakePacket(header_, quic::QuicFrame(quic_frame));
ckrasicda193a82016-07-09 00:39:36988}
989
ckrasic769733c2016-06-30 00:42:13990// If |offset| is provided, will use the value when creating the packet.
991// Will also update the value after packet creation.
Ryan Hamilton8d9ee76e2018-05-29 23:52:52992std::unique_ptr<quic::QuicReceivedPacket>
danakjad1777e2016-04-16 00:56:42993QuicTestPacketMaker::MakeResponseHeadersPacket(
Fan Yangac867502019-01-28 21:10:23994 uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:52995 quic::QuicStreamId stream_id,
zhongyi32569c62016-01-08 02:54:30996 bool should_include_version,
997 bool fin,
Ryan Hamilton0239aac2018-05-19 00:03:13998 spdy::SpdyHeaderBlock headers,
Ryan Hamilton0d65a8c2019-06-07 00:46:02999 size_t* spdy_headers_frame_length) {
zhongyi32569c62016-01-08 02:54:301000 InitializeHeader(packet_number, should_include_version);
Ryan Hamiltona1d1f4a2019-06-26 14:43:041001
1002 if (quic::VersionUsesQpack(version_.transport_version)) {
1003 // STREAM frames for HEADERS.
1004 std::vector<std::string> data = QpackEncodeHeaders(
1005 stream_id, std::move(headers), spdy_headers_frame_length);
Ryan Hamiltona1d1f4a2019-06-26 14:43:041006
1007 quic::QuicFrames frames;
Ryan Hamilton0564d0c2019-08-22 01:41:431008 for (const auto& frame : GenerateNextStreamFrames(stream_id, fin, data))
1009 frames.push_back(frame);
Ryan Hamiltona1d1f4a2019-06-26 14:43:041010 return MakeMultipleFramesPacket(header_, frames, nullptr);
1011 }
1012
Ryan Hamilton0239aac2018-05-19 00:03:131013 spdy::SpdySerializedFrame spdy_frame;
1014 spdy::SpdyHeadersIR headers_frame(stream_id, std::move(headers));
yasongc90cb532016-11-27 02:33:291015 headers_frame.set_fin(fin);
1016 spdy_frame = spdy_response_framer_.SerializeFrame(headers_frame);
1017
zhongyi32569c62016-01-08 02:54:301018 if (spdy_headers_frame_length) {
bncb03b1092016-04-06 11:19:551019 *spdy_headers_frame_length = spdy_frame.size();
zhongyi32569c62016-01-08 02:54:301020 }
Ryan Hamilton0564d0c2019-08-22 01:41:431021 return MakePacket(header_, GenerateNextStreamFrame(
1022 GetHeadersStreamId(), false,
1023 quic::QuicStringPiece(spdy_frame.data(),
1024 spdy_frame.size())));
sclittlec4dc1a32015-09-24 00:15:451025}
1026
Ryan Hamilton0239aac2018-05-19 00:03:131027spdy::SpdyHeaderBlock QuicTestPacketMaker::GetRequestHeaders(
[email protected]1e960032013-12-20 19:00:201028 const std::string& method,
1029 const std::string& scheme,
1030 const std::string& path) {
Ryan Hamilton0239aac2018-05-19 00:03:131031 spdy::SpdyHeaderBlock headers;
bnc7ecc1122015-09-28 13:22:491032 headers[":method"] = method;
rtenneti8a4a0732015-10-18 00:45:511033 headers[":authority"] = host_;
[email protected]1e960032013-12-20 19:00:201034 headers[":scheme"] = scheme;
bnc7ecc1122015-09-28 13:22:491035 headers[":path"] = path;
[email protected]1e960032013-12-20 19:00:201036 return headers;
1037}
1038
Ryan Hamilton0239aac2018-05-19 00:03:131039spdy::SpdyHeaderBlock QuicTestPacketMaker::ConnectRequestHeaders(
Yixin Wang46a273ec302018-01-23 17:59:561040 const std::string& host_port) {
Ryan Hamilton0239aac2018-05-19 00:03:131041 spdy::SpdyHeaderBlock headers;
Yixin Wang46a273ec302018-01-23 17:59:561042 headers[":method"] = "CONNECT";
1043 headers[":authority"] = host_port;
1044 return headers;
1045}
1046
Ryan Hamilton0239aac2018-05-19 00:03:131047spdy::SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
[email protected]1e960032013-12-20 19:00:201048 const std::string& status) {
Ryan Hamilton0239aac2018-05-19 00:03:131049 spdy::SpdyHeaderBlock headers;
[email protected]1e960032013-12-20 19:00:201050 headers[":status"] = status;
[email protected]1e960032013-12-20 19:00:201051 headers["content-type"] = "text/plain";
1052 return headers;
1053}
1054
Ryan Hamilton0239aac2018-05-19 00:03:131055spdy::SpdyHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
zhongyi32569c62016-01-08 02:54:301056 const std::string& status,
1057 const std::string& alt_svc) {
Ryan Hamilton0239aac2018-05-19 00:03:131058 spdy::SpdyHeaderBlock headers;
zhongyi32569c62016-01-08 02:54:301059 headers[":status"] = status;
zhongyi58bed462016-08-11 00:53:591060 headers["alt-svc"] = alt_svc;
zhongyi32569c62016-01-08 02:54:301061 headers["content-type"] = "text/plain";
1062 return headers;
1063}
1064
Ryan Hamilton8d9ee76e2018-05-29 23:52:521065std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::MakePacket(
1066 const quic::QuicPacketHeader& header,
1067 const quic::QuicFrame& frame) {
1068 quic::QuicFrames frames;
[email protected]1e960032013-12-20 19:00:201069 frames.push_back(frame);
Nick Harper158da41f2019-03-04 22:17:441070 return MakeMultipleFramesPacket(header, frames, nullptr);
jri7e636642016-01-14 06:57:081071}
1072
Ryan Hamilton8d9ee76e2018-05-29 23:52:521073std::unique_ptr<quic::QuicReceivedPacket>
1074QuicTestPacketMaker::MakeMultipleFramesPacket(
1075 const quic::QuicPacketHeader& header,
Nick Harper158da41f2019-03-04 22:17:441076 const quic::QuicFrames& frames,
1077 quic::QuicStreamFrameDataProducer* data_producer) {
Nick Harper23290b82019-05-02 00:02:561078 quic::QuicFramer framer(quic::test::SupportedVersions(version_),
Victor Vasiliev49c25142019-03-08 04:40:471079 clock_->Now(), perspective_,
1080 quic::kQuicDefaultConnectionIdLength);
Nick Harper158da41f2019-03-04 22:17:441081 if (data_producer != nullptr) {
1082 framer.set_data_producer(data_producer);
1083 }
Ryan Hamiltone940bd12019-06-30 02:46:451084 quic::QuicFrames frames_copy = CloneFrames(frames);
Renjie4a3b740b2018-09-21 00:07:541085 size_t max_plaintext_size =
1086 framer.GetMaxPlaintextSize(quic::kDefaultMaxPacketSize);
Nick Harperb16c354b2019-05-07 19:30:431087 if (version_.HasHeaderProtection()) {
1088 size_t packet_size =
1089 quic::GetPacketHeaderSize(version_.transport_version, header);
1090 size_t frames_size = 0;
1091 for (size_t i = 0; i < frames.size(); ++i) {
1092 bool first_frame = i == 0;
1093 bool last_frame = i == frames.size() - 1;
1094 const size_t frame_size = framer.GetSerializedFrameLength(
1095 frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
1096 header.packet_number_length);
1097 packet_size += frame_size;
1098 frames_size += frame_size;
1099 }
1100 // This should be done by calling QuicPacketCreator::MinPlaintextPacketSize.
1101 const size_t min_plaintext_size = 7;
1102 if (frames_size < min_plaintext_size) {
1103 size_t padding_length = min_plaintext_size - frames_size;
1104 frames_copy.push_back(
1105 quic::QuicFrame(quic::QuicPaddingFrame(padding_length)));
1106 }
1107 }
Renjie4a3b740b2018-09-21 00:07:541108 std::unique_ptr<quic::QuicPacket> packet(quic::test::BuildUnsizedDataPacket(
Nick Harperb16c354b2019-05-07 19:30:431109 &framer, header, frames_copy, max_plaintext_size));
Zhongyi Shica576df2019-04-12 17:43:401110 char buffer[quic::kMaxOutgoingPacketSize];
Ryan Hamilton8d9ee76e2018-05-29 23:52:521111 size_t encrypted_size =
Ryan Hamilton840358c2019-03-19 19:00:351112 framer.EncryptPayload(quic::ENCRYPTION_INITIAL, header.packet_number,
Zhongyi Shica576df2019-04-12 17:43:401113 *packet, buffer, quic::kMaxOutgoingPacketSize);
rch99b644c2015-11-04 05:25:281114 EXPECT_NE(0u, encrypted_size);
Ryan Hamilton8d9ee76e2018-05-29 23:52:521115 quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
1116 false);
Ryan Hamiltone940bd12019-06-30 02:46:451117 if (save_packet_frames_) {
1118 saved_frames_[header.packet_number] = frames_copy;
1119 } else {
Ryan Hamiltonceb429bc2019-08-23 03:26:391120 saved_stream_data_.clear();
Ryan Hamiltone940bd12019-06-30 02:46:451121 DeleteFrames(&frames_copy);
1122 }
Ryan Hamiltonb5afe582018-06-15 20:56:231123 return encrypted.Clone();
[email protected]1e960032013-12-20 19:00:201124}
1125
Fan Yangac867502019-01-28 21:10:231126void QuicTestPacketMaker::InitializeHeader(uint64_t packet_number,
rtennetia004d332015-08-28 06:44:571127 bool should_include_version) {
David Schinazi83d21162019-06-21 18:07:421128 header_.destination_connection_id = DestinationConnectionId();
Victor Vasilievf9693f02019-03-05 22:11:001129 header_.destination_connection_id_included = HasDestinationConnectionId();
David Schinazi83d21162019-06-21 18:07:421130 header_.source_connection_id = SourceConnectionId();
Victor Vasilievf9693f02019-03-05 22:11:001131 header_.source_connection_id_included = HasSourceConnectionId();
Jana Iyengar14683692017-11-03 05:43:421132 header_.reset_flag = false;
Fan Yang961ef182018-04-24 12:49:341133 header_.version_flag = ShouldIncludeVersion(should_include_version);
1134 header_.long_packet_type = long_header_type_;
1135 header_.packet_number_length = GetPacketNumberLength();
Fan Yangac867502019-01-28 21:10:231136 header_.packet_number = quic::QuicPacketNumber(packet_number);
Nick Harper23290b82019-05-02 00:02:561137 if (quic::QuicVersionHasLongHeaderLengths(version_.transport_version) &&
David Schinazi83d21162019-06-21 18:07:421138 header_.version_flag) {
Michael Warres167db3e2019-03-01 21:38:031139 if (long_header_type_ == quic::INITIAL) {
1140 header_.retry_token_length_length =
1141 quic::VARIABLE_LENGTH_INTEGER_LENGTH_1;
1142 }
1143 header_.length_length = quic::VARIABLE_LENGTH_INTEGER_LENGTH_2;
1144 }
[email protected]1e960032013-12-20 19:00:201145}
1146
Ryan Hamilton8d9ee76e2018-05-29 23:52:521147std::unique_ptr<quic::QuicReceivedPacket>
Ryan Hamilton0d65a8c2019-06-07 00:46:021148QuicTestPacketMaker::MakeSettingsPacket(uint64_t packet_number,
1149 bool should_include_version) {
Renjie9f172e42019-06-13 18:15:441150 if (!quic::VersionHasStreamType(version_.transport_version)) {
1151 spdy::SpdySettingsIR settings_frame;
1152 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
Bence Béky3a76c142019-07-16 23:53:161153 kQuicMaxHeaderListSize);
Renjie9f172e42019-06-13 18:15:441154 spdy::SpdySerializedFrame spdy_frame(
1155 spdy_request_framer_.SerializeFrame(settings_frame));
Ryan Hamiltone940bd12019-06-30 02:46:451156 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton0564d0c2019-08-22 01:41:431157 return MakePacket(header_, GenerateNextStreamFrame(
1158 GetHeadersStreamId(), false,
1159 quic::QuicStringPiece(spdy_frame.data(),
1160 spdy_frame.size())));
Renjie9f172e42019-06-13 18:15:441161 }
Ryan Hamiltona42582ef2019-08-23 04:09:361162
Renjie9f172e42019-06-13 18:15:441163 quic::QuicFrames frames;
Ryan Hamiltona42582ef2019-08-23 04:09:361164 MaybeAddHttp3SettingsFrames(&frames);
Ryan Hamiltone940bd12019-06-30 02:46:451165 InitializeHeader(packet_number, /*should_include_version*/ true);
1166 return MakeMultipleFramesPacket(header_, frames, nullptr);
1167}
1168
1169std::unique_ptr<quic::QuicReceivedPacket>
1170QuicTestPacketMaker::MakeInitialSettingsPacket(uint64_t packet_number) {
1171 if (!quic::VersionHasStreamType(version_.transport_version)) {
1172 spdy::SpdySettingsIR settings_frame;
1173 settings_frame.AddSetting(spdy::SETTINGS_MAX_HEADER_LIST_SIZE,
Bence Béky3a76c142019-07-16 23:53:161174 kQuicMaxHeaderListSize);
Ryan Hamiltone940bd12019-06-30 02:46:451175 spdy::SpdySerializedFrame spdy_frame(
1176 spdy_request_framer_.SerializeFrame(settings_frame));
1177 InitializeHeader(packet_number, /*should_include_version*/ true);
Ryan Hamilton0564d0c2019-08-22 01:41:431178 return MakePacket(header_, GenerateNextStreamFrame(
1179 GetHeadersStreamId(), false,
1180 quic::QuicStringPiece(spdy_frame.data(),
1181 spdy_frame.size())));
Ryan Hamiltone940bd12019-06-30 02:46:451182 }
1183 quic::QuicFrames frames;
Ryan Hamilton9f2eac32019-06-27 03:15:541184
Ryan Hamiltona42582ef2019-08-23 04:09:361185 MaybeAddHttp3SettingsFrames(&frames);
Ryan Hamilton05c0f592019-08-21 19:53:161186
Ryan Hamilton9f2eac32019-06-27 03:15:541187 InitializeHeader(packet_number, /*should_include_version*/ true);
Renjie9f172e42019-06-13 18:15:441188 return MakeMultipleFramesPacket(header_, frames, nullptr);
fayang3bcb8b502016-12-07 21:44:371189}
1190
Ryan Hamilton8d9ee76e2018-05-29 23:52:521191std::unique_ptr<quic::QuicReceivedPacket>
Fan Yangac867502019-01-28 21:10:231192QuicTestPacketMaker::MakePriorityPacket(uint64_t packet_number,
Ryan Hamilton8d9ee76e2018-05-29 23:52:521193 bool should_include_version,
1194 quic::QuicStreamId id,
1195 quic::QuicStreamId parent_stream_id,
Ryan Hamilton0d65a8c2019-06-07 00:46:021196 spdy::SpdyPriority priority) {
Ryan Hamiltone940bd12019-06-30 02:46:451197 if (!client_headers_include_h2_stream_dependency_ ||
1198 quic::VersionUsesQpack(version_.transport_version)) {
1199 // TODO(rch): both stream_dependencies and priority frames need to be
1200 // supported in IETF QUIC.
Yixin Wangb470bc882018-02-15 18:43:571201 parent_stream_id = 0;
1202 }
Ryan Hamilton0239aac2018-05-19 00:03:131203 int weight = spdy::Spdy3PriorityToHttp2Weight(priority);
Yixin Wangb470bc882018-02-15 18:43:571204 bool exclusive = client_headers_include_h2_stream_dependency_;
Renjie Tang703fea92019-07-23 21:08:311205 if (!VersionUsesQpack(version_.transport_version)) {
1206 spdy::SpdyPriorityIR priority_frame(id, parent_stream_id, weight,
1207 exclusive);
1208 spdy::SpdySerializedFrame spdy_frame(
1209 spdy_request_framer_.SerializeFrame(priority_frame));
Yixin Wangb470bc882018-02-15 18:43:571210
Renjie Tang703fea92019-07-23 21:08:311211 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton0564d0c2019-08-22 01:41:431212 return MakePacket(header_, GenerateNextStreamFrame(
1213 GetHeadersStreamId(), false,
1214 quic::QuicStringPiece(spdy_frame.data(),
1215 spdy_frame.size())));
Renjie Tang703fea92019-07-23 21:08:311216 }
1217 quic::PriorityFrame frame;
1218 frame.weight = weight;
1219 frame.exclusive = true;
1220 frame.prioritized_element_id = id;
1221 frame.element_dependency_id = parent_stream_id;
1222 frame.dependency_type = quic::REQUEST_STREAM;
1223 frame.prioritized_type =
1224 quic::QuicUtils::IsServerInitiatedStreamId(version_.transport_version, id)
1225 ? quic::PUSH_STREAM
1226 : quic::REQUEST_STREAM;
1227 std::unique_ptr<char[]> buffer;
1228 quic::QuicByteCount frame_length =
1229 http_encoder_.SerializePriorityFrame(frame, &buffer);
1230 std::string priority_data = std::string(buffer.get(), frame_length);
1231
Yixin Wang385652a2018-02-16 02:37:231232 InitializeHeader(packet_number, should_include_version);
Ryan Hamilton0564d0c2019-08-22 01:41:431233 return MakePacket(header_, GenerateNextStreamFrame(2, false, priority_data));
Yixin Wangb470bc882018-02-15 18:43:571234}
1235
Ryan Hamilton8d9ee76e2018-05-29 23:52:521236std::unique_ptr<quic::QuicReceivedPacket>
Yixin Wange7ecc472018-03-06 19:00:251237QuicTestPacketMaker::MakeAckAndMultiplePriorityFramesPacket(
Fan Yangac867502019-01-28 21:10:231238 uint64_t packet_number,
Yixin Wang385652a2018-02-16 02:37:231239 bool should_include_version,
Fan Yangac867502019-01-28 21:10:231240 uint64_t largest_received,
1241 uint64_t smallest_received,
1242 uint64_t least_unacked,
Ryan Hamilton0d65a8c2019-06-07 00:46:021243 const std::vector<Http2StreamDependency>& priority_frames) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521244 quic::QuicAckFrame ack(MakeAckFrame(largest_received));
1245 ack.ack_delay_time = quic::QuicTime::Delta::Zero();
Fan Yangac867502019-01-28 21:10:231246 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
1247 ack.received_packet_times.push_back(
1248 std::make_pair(quic::QuicPacketNumber(i), clock_->Now()));
Yixin Wang385652a2018-02-16 02:37:231249 }
1250 if (largest_received > 0) {
Fan Yangac867502019-01-28 21:10:231251 ack.packets.AddRange(quic::QuicPacketNumber(1),
1252 quic::QuicPacketNumber(largest_received + 1));
Yixin Wang385652a2018-02-16 02:37:231253 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521254 quic::QuicFrames frames;
1255 frames.push_back(quic::QuicFrame(&ack));
Zhongyi Shicbe75b32018-05-30 05:20:281256 DVLOG(1) << "Adding frame: " << frames.back();
Yixin Wang385652a2018-02-16 02:37:231257
Yixin Wange7ecc472018-03-06 19:00:251258 const bool exclusive = client_headers_include_h2_stream_dependency_;
Yixin Wange7ecc472018-03-06 19:00:251259 // Keep SpdySerializedFrames alive until MakeMultipleFramesPacket is done.
Ryan Hamilton0239aac2018-05-19 00:03:131260 std::vector<std::unique_ptr<spdy::SpdySerializedFrame>> spdy_frames;
Yixin Wange7ecc472018-03-06 19:00:251261 for (const Http2StreamDependency& info : priority_frames) {
Ryan Hamilton0239aac2018-05-19 00:03:131262 spdy::SpdyPriorityIR priority_frame(
Yixin Wange7ecc472018-03-06 19:00:251263 info.stream_id, info.parent_stream_id,
Ryan Hamilton0239aac2018-05-19 00:03:131264 spdy::Spdy3PriorityToHttp2Weight(info.spdy_priority), exclusive);
Yixin Wange7ecc472018-03-06 19:00:251265
Ryan Hamilton0239aac2018-05-19 00:03:131266 spdy_frames.push_back(std::make_unique<spdy::SpdySerializedFrame>(
Yixin Wange7ecc472018-03-06 19:00:251267 spdy_request_framer_.SerializeFrame(priority_frame)));
1268
Ryan Hamilton0239aac2018-05-19 00:03:131269 spdy::SpdySerializedFrame* spdy_frame = spdy_frames.back().get();
Ryan Hamilton0564d0c2019-08-22 01:41:431270 frames.push_back(GenerateNextStreamFrame(
Bence Béky7d168142019-08-06 17:10:231271 quic::VersionUsesQpack(version_.transport_version)
1272 ? GetFirstBidirectionalStreamId()
1273 : GetHeadersStreamId(),
Ryan Hamilton0564d0c2019-08-22 01:41:431274 false, quic::QuicStringPiece(spdy_frame->data(), spdy_frame->size())));
Yixin Wange7ecc472018-03-06 19:00:251275 }
Yixin Wang385652a2018-02-16 02:37:231276
1277 InitializeHeader(packet_number, should_include_version);
Nick Harper158da41f2019-03-04 22:17:441278 return MakeMultipleFramesPacket(header_, frames, nullptr);
Yixin Wang385652a2018-02-16 02:37:231279}
1280
Ryan Hamiltone940bd12019-06-30 02:46:451281std::unique_ptr<quic::QuicReceivedPacket>
1282QuicTestPacketMaker::MakeRetransmissionPacket(uint64_t original_packet_number,
1283 uint64_t new_packet_number,
1284 bool should_include_version) {
1285 DCHECK(save_packet_frames_);
1286 InitializeHeader(new_packet_number, should_include_version);
1287 return MakeMultipleFramesPacket(
1288 header_, saved_frames_[quic::QuicPacketNumber(original_packet_number)],
1289 nullptr);
1290}
1291
Ryan Hamiltonb01f886f2019-07-10 02:25:551292void QuicTestPacketMaker::RemoveSavedStreamFrames(
1293 quic::QuicStreamId stream_id) {
1294 for (auto& kv : saved_frames_) {
1295 auto it = kv.second.begin();
1296 while (it != kv.second.end()) {
1297 if (it->type == quic::STREAM_FRAME &&
1298 it->stream_frame.stream_id == stream_id) {
1299 it = kv.second.erase(it);
1300 } else {
1301 ++it;
1302 }
1303 }
1304 }
1305}
1306
Ryan Hamilton8d9ee76e2018-05-29 23:52:521307void QuicTestPacketMaker::SetEncryptionLevel(quic::EncryptionLevel level) {
Fan Yang961ef182018-04-24 12:49:341308 encryption_level_ = level;
Fan Yangc576d4de2019-02-14 15:56:241309 switch (level) {
Ryan Hamilton840358c2019-03-19 19:00:351310 case quic::ENCRYPTION_INITIAL:
Fan Yangc576d4de2019-02-14 15:56:241311 long_header_type_ = quic::INITIAL;
1312 break;
Michael Warres167db3e2019-03-01 21:38:031313 case quic::ENCRYPTION_ZERO_RTT:
Fan Yangc576d4de2019-02-14 15:56:241314 long_header_type_ = quic::ZERO_RTT_PROTECTED;
1315 break;
1316 case quic::ENCRYPTION_FORWARD_SECURE:
1317 long_header_type_ = quic::INVALID_PACKET_TYPE;
1318 break;
1319 default:
1320 QUIC_BUG << quic::QuicUtils::EncryptionLevelToString(level);
1321 long_header_type_ = quic::INVALID_PACKET_TYPE;
1322 }
Fan Yang961ef182018-04-24 12:49:341323}
1324
1325bool QuicTestPacketMaker::ShouldIncludeVersion(bool include_version) const {
Nick Harper23290b82019-05-02 00:02:561326 if (version_.transport_version > quic::QUIC_VERSION_43) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521327 return encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE;
Fan Yang961ef182018-04-24 12:49:341328 }
1329 return include_version;
1330}
1331
Bence Békyc7a29c02019-08-07 02:26:341332std::string QuicTestPacketMaker::MaybePrependErrorCode(
1333 const std::string& quic_error_details,
1334 quic::QuicErrorCode quic_error_code) const {
1335 if (!quic::VersionHasIetfQuicFrames(version_.transport_version) ||
1336 quic_error_code == quic::QUIC_IETF_GQUIC_ERROR_MISSING) {
1337 // QUIC_IETF_GQUIC_ERROR_MISSING means not to encode the error value.
1338 return quic_error_details;
1339 }
1340 return base::StrCat(
1341 {base::NumberToString(quic_error_code), ":", quic_error_details});
1342}
1343
Ryan Hamilton0564d0c2019-08-22 01:41:431344quic::QuicFrame QuicTestPacketMaker::GenerateNextStreamFrame(
Ryan Hamilton7505eb92019-06-08 00:22:171345 quic::QuicStreamId stream_id,
1346 bool fin,
1347 quic::QuicStringPiece data) {
Ryan Hamiltonceb429bc2019-08-23 03:26:391348 // Save the stream data so that callers can use temporary objects for data.
1349 saved_stream_data_.push_back(std::make_unique<std::string>(data));
1350 data = *saved_stream_data_.back();
1351
Ryan Hamilton7505eb92019-06-08 00:22:171352 quic::QuicStreamFrame frame(stream_id, fin, stream_offsets_[stream_id], data);
1353 stream_offsets_[stream_id] += data.length();
Ryan Hamiltona1d1f4a2019-06-26 14:43:041354 DVLOG(1) << "Adding frame: " << frame;
Ryan Hamilton0564d0c2019-08-22 01:41:431355 return quic::QuicFrame(frame);
Ryan Hamilton7505eb92019-06-08 00:22:171356}
1357
Ryan Hamiltona1d1f4a2019-06-26 14:43:041358std::vector<std::string> QuicTestPacketMaker::QpackEncodeHeaders(
1359 quic::QuicStreamId stream_id,
1360 spdy::SpdyHeaderBlock headers,
1361 size_t* encoded_data_length) {
1362 DCHECK(quic::VersionUsesQpack(version_.transport_version));
1363 std::vector<std::string> data;
1364
1365 std::string encoded_headers =
Nick Harper057264a82019-09-12 23:33:491366 qpack_encoder_.EncodeHeaderList(stream_id, headers, nullptr);
Ryan Hamiltona1d1f4a2019-06-26 14:43:041367
1368 // Generate HEADERS frame header.
1369 std::unique_ptr<char[]> headers_frame_header;
1370 const size_t headers_frame_header_length =
1371 http_encoder_.SerializeHeadersFrameHeader(encoded_headers.size(),
1372 &headers_frame_header);
1373
1374 // Possible add a PUSH stream type.
1375 if (!quic::QuicUtils::IsBidirectionalStreamId(stream_id) &&
1376 stream_offsets_[stream_id] == 0) {
1377 // Push stream type header
1378 data.push_back("\x01");
1379 }
1380
1381 // Add the HEADERS frame header.
1382 data.push_back(
1383 std::string(headers_frame_header.get(), headers_frame_header_length));
1384 // Add the HEADERS frame payload.
1385 data.push_back(encoded_headers);
1386
Ryan Hamilton9f2eac32019-06-27 03:15:541387 if (coalesce_http_frames_) {
1388 std::string coalesced;
1389 for (const auto& d : data) {
1390 coalesced += d;
1391 }
1392 data = {coalesced};
1393 }
1394
Ryan Hamiltona1d1f4a2019-06-26 14:43:041395 // Compute the total data length.
1396 if (encoded_data_length) {
1397 *encoded_data_length = 0;
1398 for (const auto& d : data)
1399 *encoded_data_length += d.length();
1400 }
1401 return data;
1402}
1403
Ryan Hamilton0564d0c2019-08-22 01:41:431404std::vector<quic::QuicFrame> QuicTestPacketMaker::GenerateNextStreamFrames(
Ryan Hamiltona1d1f4a2019-06-26 14:43:041405 quic::QuicStreamId stream_id,
1406 bool fin,
1407 const std::vector<std::string>& data) {
Ryan Hamilton0564d0c2019-08-22 01:41:431408 std::vector<quic::QuicFrame> frames;
Ryan Hamiltona1d1f4a2019-06-26 14:43:041409 for (size_t i = 0; i < data.size(); ++i) {
1410 const bool frame_fin = i == data.size() - 1 && fin;
Ryan Hamilton0564d0c2019-08-22 01:41:431411 frames.push_back(GenerateNextStreamFrame(stream_id, frame_fin, data[i]));
Ryan Hamiltona1d1f4a2019-06-26 14:43:041412 }
1413 return frames;
1414}
1415
Ryan Hamilton8d9ee76e2018-05-29 23:52:521416quic::QuicPacketNumberLength QuicTestPacketMaker::GetPacketNumberLength()
1417 const {
Nick Harper23290b82019-05-02 00:02:561418 if (version_.transport_version > quic::QUIC_VERSION_43 &&
Zhongyi Shi1dd87f892019-01-03 05:24:481419 encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE &&
Renjie9522db42019-06-15 03:20:001420 !version_.SendsVariableLengthPacketNumberInLongHeader()) {
Ryan Hamilton8d9ee76e2018-05-29 23:52:521421 return quic::PACKET_4BYTE_PACKET_NUMBER;
Fan Yang961ef182018-04-24 12:49:341422 }
Ryan Hamilton8d9ee76e2018-05-29 23:52:521423 return quic::PACKET_1BYTE_PACKET_NUMBER;
Fan Yang961ef182018-04-24 12:49:341424}
1425
David Schinazi83d21162019-06-21 18:07:421426quic::QuicConnectionId QuicTestPacketMaker::DestinationConnectionId() const {
Fan Yang2330d182019-08-05 14:50:501427 if (perspective_ == quic::Perspective::IS_SERVER) {
David Schinazi83d21162019-06-21 18:07:421428 return quic::EmptyQuicConnectionId();
1429 }
1430 return connection_id_;
1431}
1432
1433quic::QuicConnectionId QuicTestPacketMaker::SourceConnectionId() const {
Fan Yang2330d182019-08-05 14:50:501434 if (perspective_ == quic::Perspective::IS_CLIENT) {
David Schinazi83d21162019-06-21 18:07:421435 return quic::EmptyQuicConnectionId();
1436 }
1437 return connection_id_;
1438}
1439
Victor Vasilievf9693f02019-03-05 22:11:001440quic::QuicConnectionIdIncluded QuicTestPacketMaker::HasDestinationConnectionId()
1441 const {
David Schinazi83d21162019-06-21 18:07:421442 if (!version_.SupportsClientConnectionIds() &&
Fan Yang2330d182019-08-05 14:50:501443 perspective_ == quic::Perspective::IS_SERVER) {
Victor Vasilievf9693f02019-03-05 22:11:001444 return quic::CONNECTION_ID_ABSENT;
Fan Yang9182e5e2018-06-09 02:07:081445 }
Victor Vasilievf9693f02019-03-05 22:11:001446 return quic::CONNECTION_ID_PRESENT;
Fan Yang9182e5e2018-06-09 02:07:081447}
1448
Victor Vasilievf9693f02019-03-05 22:11:001449quic::QuicConnectionIdIncluded QuicTestPacketMaker::HasSourceConnectionId()
Fan Yang9182e5e2018-06-09 02:07:081450 const {
David Schinazi83d21162019-06-21 18:07:421451 if (version_.SupportsClientConnectionIds() ||
1452 (perspective_ == quic::Perspective::IS_SERVER &&
Fan Yang2330d182019-08-05 14:50:501453 encryption_level_ < quic::ENCRYPTION_FORWARD_SECURE)) {
Victor Vasilievf9693f02019-03-05 22:11:001454 return quic::CONNECTION_ID_PRESENT;
Fan Yang9182e5e2018-06-09 02:07:081455 }
Victor Vasilievf9693f02019-03-05 22:11:001456 return quic::CONNECTION_ID_ABSENT;
Fan Yang9182e5e2018-06-09 02:07:081457}
1458
Ryan Hamilton0d65a8c2019-06-07 00:46:021459void QuicTestPacketMaker::Reset() {
Ryan Hamiltona1d1f4a2019-06-26 14:43:041460 for (const auto& kv : stream_offsets_)
Ryan Hamilton7505eb92019-06-08 00:22:171461 stream_offsets_[kv.first] = 0;
Ryan Hamilton0d65a8c2019-06-07 00:46:021462}
1463
Bence Béky7d168142019-08-06 17:10:231464quic::QuicStreamId QuicTestPacketMaker::GetFirstBidirectionalStreamId() const {
1465 return quic::QuicUtils::GetFirstBidirectionalStreamId(
1466 version_.transport_version, perspective_);
1467}
1468
1469quic::QuicStreamId QuicTestPacketMaker::GetHeadersStreamId() const {
1470 return quic::QuicUtils::GetHeadersStreamId(version_.transport_version);
1471}
1472
Ryan Hamilton2a9f45a2019-08-22 18:28:381473std::string QuicTestPacketMaker::GenerateHttp3SettingsData() {
1474 quic::SettingsFrame settings;
1475 settings.values[quic::SETTINGS_MAX_HEADER_LIST_SIZE] = kQuicMaxHeaderListSize;
1476 settings.values[quic::SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
1477 quic::kDefaultQpackMaxDynamicTableCapacity;
1478 std::unique_ptr<char[]> buffer;
1479 quic::QuicByteCount frame_length =
1480 http_encoder_.SerializeSettingsFrame(settings, &buffer);
1481 return std::string(buffer.get(), frame_length);
1482}
1483
1484std::string QuicTestPacketMaker::GenerateHttp3PriorityData(
1485 spdy::SpdyPriority priority,
1486 quic::QuicStreamId stream_id) {
1487 quic::PriorityFrame frame;
1488 frame.weight = priority;
1489 frame.dependency_type = quic::ROOT_OF_TREE;
1490 frame.prioritized_type = quic::REQUEST_STREAM;
1491 frame.prioritized_element_id = stream_id;
1492
1493 std::unique_ptr<char[]> buffer;
1494 quic::QuicByteCount frame_length =
1495 http_encoder_.SerializePriorityFrame(frame, &buffer);
1496 return std::string(buffer.get(), frame_length);
1497}
1498
Ryan Hamiltona42582ef2019-08-23 04:09:361499void QuicTestPacketMaker::MaybeAddHttp3SettingsFrames(
1500 quic::QuicFrames* frames) {
1501 DCHECK(quic::VersionUsesQpack(version_.transport_version));
1502
1503 quic::QuicStreamId stream_id =
1504 quic::QuicUtils::GetFirstUnidirectionalStreamId(
1505 version_.transport_version, perspective_);
1506
1507 if (stream_offsets_[stream_id] != 0)
1508 return;
1509
1510 // A stream frame containing stream type will be written on the control
1511 // stream first.
1512 std::string type(1, 0x00);
1513 std::string settings_data = GenerateHttp3SettingsData();
1514
1515 // The type and the SETTINGS frame may be sent in multiple QUIC STREAM
1516 // frames.
1517 std::vector<std::string> data;
1518 if (coalesce_http_frames_) {
1519 data = {type + settings_data};
1520 } else {
1521 data = {type, settings_data};
1522 }
1523
1524 for (const auto& frame : GenerateNextStreamFrames(stream_id, false, data))
1525 frames->push_back(frame);
Ryan Hamilton93424eb82019-08-23 04:28:401526
1527 if (coalesce_http_frames_) {
1528 frames->push_back(GenerateNextStreamFrame(stream_id + 4, false, "\x03"));
1529 frames->push_back(GenerateNextStreamFrame(stream_id + 8, false, "\x02"));
1530 } else {
1531 frames->push_back(GenerateNextStreamFrame(stream_id + 8, false, "\x02"));
1532 frames->push_back(GenerateNextStreamFrame(stream_id + 4, false, "\x03"));
1533 }
Ryan Hamiltona42582ef2019-08-23 04:09:361534}
1535
[email protected]1e960032013-12-20 19:00:201536} // namespace test
1537} // namespace net