1 // Copyright 2013 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifdef UNSAFE_BUFFERS_BUILD
6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors.
7 #pragma allow_unsafe_buffers
8 #endif
9
10 #include "net/quic/quic_test_packet_maker.h"
11
12 #include <list>
13 #include <utility>
14
15 #include "base/functional/callback.h"
16 #include "base/strings/strcat.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/test/bind.h"
19 #include "net/base/features.h"
20 #include "net/quic/mock_crypto_client_stream.h"
21 #include "net/quic/quic_chromium_client_session.h"
22 #include "net/quic/quic_http_utils.h"
23 #include "net/spdy/spdy_http_utils.h"
24 #include "net/third_party/quiche/src/quiche/common/quiche_buffer_allocator.h"
25 #include "net/third_party/quiche/src/quiche/common/simple_buffer_allocator.h"
26 #include "net/third_party/quiche/src/quiche/quic/core/http/http_constants.h"
27 #include "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_instruction_encoder.h"
28 #include "net/third_party/quiche/src/quiche/quic/core/quic_framer.h"
29 #include "net/third_party/quiche/src/quiche/quic/core/quic_stream.h"
30 #include "net/third_party/quiche/src/quiche/quic/core/quic_types.h"
31 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
32 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h"
33 #include "net/third_party/quiche/src/quiche/quic/test_tools/quic_test_utils.h"
34
35 namespace net::test {
36 namespace {
37
CloneFrames(const quic::QuicFrames & frames)38 quic::QuicFrames CloneFrames(const quic::QuicFrames& frames) {
39 quic::QuicFrames new_frames = frames;
40 for (auto& frame : new_frames) {
41 switch (frame.type) {
42 // Frames smaller than a pointer are inlined, so don't need to be cloned.
43 case quic::PADDING_FRAME:
44 case quic::MTU_DISCOVERY_FRAME:
45 case quic::PING_FRAME:
46 case quic::MAX_STREAMS_FRAME:
47 case quic::STOP_WAITING_FRAME:
48 case quic::STREAMS_BLOCKED_FRAME:
49 case quic::STREAM_FRAME:
50 case quic::HANDSHAKE_DONE_FRAME:
51 case quic::BLOCKED_FRAME:
52 case quic::WINDOW_UPDATE_FRAME:
53 case quic::STOP_SENDING_FRAME:
54 case quic::PATH_CHALLENGE_FRAME:
55 case quic::PATH_RESPONSE_FRAME:
56 break;
57 case quic::ACK_FRAME:
58 frame.ack_frame = new quic::QuicAckFrame(*frame.ack_frame);
59 break;
60 case quic::RST_STREAM_FRAME:
61 frame.rst_stream_frame =
62 new quic::QuicRstStreamFrame(*frame.rst_stream_frame);
63 break;
64 case quic::CONNECTION_CLOSE_FRAME:
65 frame.connection_close_frame =
66 new quic::QuicConnectionCloseFrame(*frame.connection_close_frame);
67 break;
68 case quic::GOAWAY_FRAME:
69 frame.goaway_frame = new quic::QuicGoAwayFrame(*frame.goaway_frame);
70 break;
71 case quic::NEW_CONNECTION_ID_FRAME:
72 frame.new_connection_id_frame =
73 new quic::QuicNewConnectionIdFrame(*frame.new_connection_id_frame);
74 break;
75 case quic::RETIRE_CONNECTION_ID_FRAME:
76 frame.retire_connection_id_frame =
77 new quic::QuicRetireConnectionIdFrame(
78 *frame.retire_connection_id_frame);
79 break;
80 case quic::MESSAGE_FRAME:
81 frame.message_frame = new quic::QuicMessageFrame(
82 frame.message_frame->message_id,
83 quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
84 quiche::SimpleBufferAllocator::Get(),
85 frame.message_frame->message_data.data()->AsStringView())));
86 break;
87 case quic::CRYPTO_FRAME:
88 frame.crypto_frame = new quic::QuicCryptoFrame(*frame.crypto_frame);
89 break;
90 case quic::NEW_TOKEN_FRAME:
91 frame.new_token_frame =
92 new quic::QuicNewTokenFrame(*frame.new_token_frame);
93 break;
94 case quic::ACK_FREQUENCY_FRAME:
95 frame.ack_frequency_frame =
96 new quic::QuicAckFrequencyFrame(*frame.ack_frequency_frame);
97 break;
98 case quic::RESET_STREAM_AT_FRAME:
99 frame.reset_stream_at_frame =
100 new quic::QuicResetStreamAtFrame(*frame.reset_stream_at_frame);
101 break;
102
103 case quic::NUM_FRAME_TYPES:
104 DCHECK(false) << "Cannot clone frame type: " << frame.type;
105 }
106 }
107 return new_frames;
108 }
109
110 } // namespace
111
112 QuicTestPacketMaker::ConnectionState::ConnectionState() = default;
113
~ConnectionState()114 QuicTestPacketMaker::ConnectionState::~ConnectionState() {
115 for (auto& kv : saved_frames) {
116 quic::DeleteFrames(&(kv.second));
117 }
118 }
119
SaveStreamData(std::string_view data)120 std::string_view QuicTestPacketMaker::ConnectionState::SaveStreamData(
121 std::string_view data) {
122 saved_stream_data.push_back(std::make_unique<std::string>(data));
123 return *saved_stream_data.back();
124 }
125
Reset()126 void QuicTestPacketMaker::ConnectionState::Reset() {
127 stream_offsets.clear();
128 }
129
QuicTestPacketMaker(quic::ParsedQuicVersion version,quic::QuicConnectionId connection_id,const quic::QuicClock * clock,const std::string & host,quic::Perspective perspective,bool client_priority_uses_incremental,bool use_priority_header)130 QuicTestPacketMaker::QuicTestPacketMaker(quic::ParsedQuicVersion version,
131 quic::QuicConnectionId connection_id,
132 const quic::QuicClock* clock,
133 const std::string& host,
134 quic::Perspective perspective,
135 bool client_priority_uses_incremental,
136 bool use_priority_header)
137 : version_(version),
138 clock_(clock),
139 host_(host),
140 qpack_encoder_(&decoder_stream_error_delegate_,
141 quic::HuffmanEncoding::kEnabled,
142 quic::CookieCrumbling::kEnabled),
143 perspective_(perspective),
144 client_priority_uses_incremental_(client_priority_uses_incremental),
145 use_priority_header_(use_priority_header) {
146 DCHECK(version.HasIetfQuicFrames());
147 DCHECK(!(perspective_ == quic::Perspective::IS_SERVER &&
148 client_priority_uses_incremental_));
149
150 set_connection_id(connection_id);
151 qpack_encoder_.set_qpack_stream_sender_delegate(
152 &encoder_stream_sender_delegate_);
153 }
154
~QuicTestPacketMaker()155 QuicTestPacketMaker::~QuicTestPacketMaker() {
156 CHECK(!builder_) << "QuicTestPacketMacker destroyed with unfinished packet "
157 "build operation";
158 }
159
set_hostname(const std::string & host)160 void QuicTestPacketMaker::set_hostname(const std::string& host) {
161 host_.assign(host);
162 }
163
Packet(uint64_t packet_number)164 QuicTestPacketBuilder& QuicTestPacketMaker::Packet(uint64_t packet_number) {
165 CHECK(!builder_);
166 builder_ = std::make_unique<QuicTestPacketBuilder>(packet_number, this,
167 &connection_state_);
168 return *builder_.get();
169 }
170
171 std::unique_ptr<quic::QuicReceivedPacket>
MakeDummyCHLOPacket(uint64_t packet_number)172 QuicTestPacketMaker::MakeDummyCHLOPacket(uint64_t packet_number) {
173 SetEncryptionLevel(quic::ENCRYPTION_INITIAL);
174
175 auto& builder = Packet(packet_number);
176
177 quic::CryptoHandshakeMessage message =
178 MockCryptoClientStream::GetDummyCHLOMessage();
179 const quic::QuicData& data = message.GetSerialized();
180
181 builder.AddCryptoFrame(quic::ENCRYPTION_INITIAL, 0, data);
182
183 builder.AddPaddingFrame();
184 return builder.Build();
185 }
186
187 std::unique_ptr<quic::QuicReceivedPacket>
MakeAckAndRetransmissionPacket(uint64_t packet_number,uint64_t first_received,uint64_t largest_received,uint64_t smallest_received,const std::vector<uint64_t> & original_packet_numbers)188 QuicTestPacketMaker::MakeAckAndRetransmissionPacket(
189 uint64_t packet_number,
190 uint64_t first_received,
191 uint64_t largest_received,
192 uint64_t smallest_received,
193 const std::vector<uint64_t>& original_packet_numbers) {
194 DCHECK(connection_state_.save_packet_frames);
195 auto& builder = Packet(packet_number);
196 builder.AddAckFrame(first_received, largest_received, smallest_received);
197 for (auto it : original_packet_numbers) {
198 builder.AddPacketRetransmission(it);
199 }
200 return builder.Build();
201 }
202
CloneSavedFrames(uint64_t packet_number)203 quic::QuicFrames QuicTestPacketMaker::CloneSavedFrames(uint64_t packet_number) {
204 DCHECK(connection_state_.save_packet_frames);
205 return CloneFrames(
206 connection_state_.saved_frames[quic::QuicPacketNumber(packet_number)]);
207 }
208
209 std::unique_ptr<quic::QuicReceivedPacket>
MakeCombinedRetransmissionPacket(const std::vector<uint64_t> & original_packet_numbers,uint64_t new_packet_number)210 QuicTestPacketMaker::MakeCombinedRetransmissionPacket(
211 const std::vector<uint64_t>& original_packet_numbers,
212 uint64_t new_packet_number) {
213 DCHECK(connection_state_.save_packet_frames);
214 auto& builder = Packet(new_packet_number);
215 for (auto it : original_packet_numbers) {
216 for (auto& frame : CloneFrames(
217 connection_state_.saved_frames[quic::QuicPacketNumber(it)])) {
218 if (frame.type != quic::PADDING_FRAME) {
219 builder.AddFrameWithCoalescing(frame);
220 }
221 }
222 }
223 return builder.Build();
224 }
225
226 std::unique_ptr<quic::QuicReceivedPacket>
MakeAckAndDatagramPacket(uint64_t packet_number,uint64_t largest_received,uint64_t smallest_received,std::string_view data)227 QuicTestPacketMaker::MakeAckAndDatagramPacket(uint64_t packet_number,
228 uint64_t largest_received,
229 uint64_t smallest_received,
230 std::string_view data) {
231 return Packet(packet_number)
232 .AddAckFrame(/*first_received=*/1, largest_received, smallest_received)
233 .AddMessageFrame(data)
234 .Build();
235 }
236
237 std::unique_ptr<quic::QuicReceivedPacket>
MakeRequestHeadersAndMultipleDataFramesPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,spdy::SpdyPriority spdy_priority,quiche::HttpHeaderBlock headers,size_t * spdy_headers_frame_length,const std::vector<std::string> & data_writes)238 QuicTestPacketMaker::MakeRequestHeadersAndMultipleDataFramesPacket(
239 uint64_t packet_number,
240 quic::QuicStreamId stream_id,
241 bool fin,
242 spdy::SpdyPriority spdy_priority,
243 quiche::HttpHeaderBlock headers,
244 size_t* spdy_headers_frame_length,
245 const std::vector<std::string>& data_writes) {
246 auto& builder = Packet(packet_number);
247 builder.MaybeAddHttp3SettingsFrames();
248
249 std::string priority_data =
250 GenerateHttp3PriorityData(spdy_priority, stream_id);
251 if (!priority_data.empty()) {
252 builder.AddStreamFrame(2, false, priority_data);
253 }
254
255 AddPriorityHeader(spdy_priority, &headers);
256 std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
257 spdy_headers_frame_length);
258 for (const auto& data_write : data_writes) {
259 data += data_write;
260 }
261 builder.AddStreamFrame(stream_id, fin, data);
262 return builder.Build();
263 }
264
265 std::unique_ptr<quic::QuicReceivedPacket>
MakeRequestHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,spdy::SpdyPriority spdy_priority,quiche::HttpHeaderBlock headers,size_t * spdy_headers_frame_length,bool should_include_priority_frame)266 QuicTestPacketMaker::MakeRequestHeadersPacket(
267 uint64_t packet_number,
268 quic::QuicStreamId stream_id,
269 bool fin,
270 spdy::SpdyPriority spdy_priority,
271 quiche::HttpHeaderBlock headers,
272 size_t* spdy_headers_frame_length,
273 bool should_include_priority_frame) {
274 auto& builder = Packet(packet_number);
275 builder.MaybeAddHttp3SettingsFrames();
276
277 if (should_include_priority_frame) {
278 std::string priority_data =
279 GenerateHttp3PriorityData(spdy_priority, stream_id);
280 if (!priority_data.empty()) {
281 builder.AddStreamFrame(2, false, priority_data);
282 }
283 }
284
285 AddPriorityHeader(spdy_priority, &headers);
286 std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
287 spdy_headers_frame_length);
288 builder.AddStreamFrame(stream_id, fin, data);
289 return builder.Build();
290 }
291
292 std::unique_ptr<quic::QuicReceivedPacket>
MakeRetransmissionAndRequestHeadersPacket(const std::vector<uint64_t> & original_packet_numbers,uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,spdy::SpdyPriority spdy_priority,quiche::HttpHeaderBlock headers,size_t * spdy_headers_frame_length)293 QuicTestPacketMaker::MakeRetransmissionAndRequestHeadersPacket(
294 const std::vector<uint64_t>& original_packet_numbers,
295 uint64_t packet_number,
296 quic::QuicStreamId stream_id,
297 bool fin,
298 spdy::SpdyPriority spdy_priority,
299 quiche::HttpHeaderBlock headers,
300 size_t* spdy_headers_frame_length) {
301 DCHECK(connection_state_.save_packet_frames);
302 auto& builder = Packet(packet_number);
303 for (auto it : original_packet_numbers) {
304 builder.AddPacketRetransmission(it);
305 }
306
307 builder.MaybeAddHttp3SettingsFrames();
308
309 std::string priority_data =
310 GenerateHttp3PriorityData(spdy_priority, stream_id);
311 if (!priority_data.empty()) {
312 builder.AddStreamFrame(2, false, priority_data);
313 }
314
315 AddPriorityHeader(spdy_priority, &headers);
316 std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
317 spdy_headers_frame_length);
318 builder.AddStreamFrame(stream_id, fin, data);
319 return builder.Build();
320 }
321
322 std::unique_ptr<quic::QuicReceivedPacket>
MakeRequestHeadersAndRstPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,spdy::SpdyPriority spdy_priority,quiche::HttpHeaderBlock headers,size_t * spdy_headers_frame_length,quic::QuicRstStreamErrorCode error_code)323 QuicTestPacketMaker::MakeRequestHeadersAndRstPacket(
324 uint64_t packet_number,
325 quic::QuicStreamId stream_id,
326 bool fin,
327 spdy::SpdyPriority spdy_priority,
328 quiche::HttpHeaderBlock headers,
329 size_t* spdy_headers_frame_length,
330 quic::QuicRstStreamErrorCode error_code) {
331 auto& builder = Packet(packet_number);
332 builder.MaybeAddHttp3SettingsFrames();
333
334 std::string priority_data =
335 GenerateHttp3PriorityData(spdy_priority, stream_id);
336 if (!priority_data.empty()) {
337 builder.AddStreamFrame(2, false, priority_data);
338 }
339
340 AddPriorityHeader(spdy_priority, &headers);
341 std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
342 spdy_headers_frame_length);
343 builder.AddStreamFrame(stream_id, fin, data);
344 builder.AddStopSendingFrame(stream_id, error_code);
345 builder.AddRstStreamFrame(stream_id, error_code);
346 return builder.Build();
347 }
348
349 std::unique_ptr<quic::QuicReceivedPacket>
MakeResponseHeadersPacket(uint64_t packet_number,quic::QuicStreamId stream_id,bool fin,quiche::HttpHeaderBlock headers,size_t * spdy_headers_frame_length)350 QuicTestPacketMaker::MakeResponseHeadersPacket(
351 uint64_t packet_number,
352 quic::QuicStreamId stream_id,
353 bool fin,
354 quiche::HttpHeaderBlock headers,
355 size_t* spdy_headers_frame_length) {
356 std::string data = QpackEncodeHeaders(stream_id, std::move(headers),
357 spdy_headers_frame_length);
358 return Packet(packet_number).AddStreamFrame(stream_id, fin, data).Build();
359 }
360
361 std::unique_ptr<quic::QuicReceivedPacket>
MakeInitialSettingsPacket(uint64_t packet_number)362 QuicTestPacketMaker::MakeInitialSettingsPacket(uint64_t packet_number) {
363 return Packet(packet_number).MaybeAddHttp3SettingsFrames().Build();
364 }
365
366 std::unique_ptr<quic::QuicReceivedPacket>
MakePriorityPacket(uint64_t packet_number,quic::QuicStreamId id,spdy::SpdyPriority spdy_priority)367 QuicTestPacketMaker::MakePriorityPacket(uint64_t packet_number,
368 quic::QuicStreamId id,
369 spdy::SpdyPriority spdy_priority) {
370 auto& builder = Packet(packet_number);
371 std::string priority_data = GenerateHttp3PriorityData(spdy_priority, id);
372 if (!priority_data.empty()) {
373 builder.AddStreamFrame(2, false, priority_data);
374 }
375 return builder.Build();
376 }
377
378 std::unique_ptr<quic::QuicReceivedPacket>
MakeRetransmissionPacket(uint64_t original_packet_number,uint64_t new_packet_number)379 QuicTestPacketMaker::MakeRetransmissionPacket(uint64_t original_packet_number,
380 uint64_t new_packet_number) {
381 DCHECK(connection_state_.save_packet_frames);
382 auto& builder = Packet(new_packet_number);
383 builder.AddPacketRetransmission(original_packet_number);
384 return builder.Build();
385 }
386
387 std::unique_ptr<quic::QuicEncryptedPacket>
MakeStatelessResetPacket()388 QuicTestPacketMaker::MakeStatelessResetPacket() {
389 auto connection_id = quic::test::TestConnectionId();
390 return quic::QuicFramer::BuildIetfStatelessResetPacket(
391 connection_id, quic::QuicFramer::GetMinStatelessResetPacketLength() + 1,
392 quic::QuicUtils::GenerateStatelessResetToken(connection_id));
393 }
394
RemoveSavedStreamFrames(quic::QuicStreamId stream_id)395 void QuicTestPacketMaker::RemoveSavedStreamFrames(
396 quic::QuicStreamId stream_id) {
397 for (auto& kv : connection_state_.saved_frames) {
398 auto* it = kv.second.begin();
399 while (it != kv.second.end()) {
400 if (it->type == quic::STREAM_FRAME &&
401 it->stream_frame.stream_id == stream_id) {
402 it = kv.second.erase(it);
403 } else {
404 ++it;
405 }
406 }
407 }
408 }
409
SetEncryptionLevel(quic::EncryptionLevel level)410 void QuicTestPacketMaker::SetEncryptionLevel(quic::EncryptionLevel level) {
411 encryption_level_ = level;
412 switch (level) {
413 case quic::ENCRYPTION_INITIAL:
414 long_header_type_ = quic::INITIAL;
415 break;
416 case quic::ENCRYPTION_ZERO_RTT:
417 long_header_type_ = quic::ZERO_RTT_PROTECTED;
418 break;
419 case quic::ENCRYPTION_FORWARD_SECURE:
420 long_header_type_ = quic::INVALID_PACKET_TYPE;
421 break;
422 default:
423 LOG(DFATAL) << quic::EncryptionLevelToString(level);
424 long_header_type_ = quic::INVALID_PACKET_TYPE;
425 }
426 }
427
GetRequestHeaders(const std::string & method,const std::string & scheme,const std::string & path) const428 quiche::HttpHeaderBlock QuicTestPacketMaker::GetRequestHeaders(
429 const std::string& method,
430 const std::string& scheme,
431 const std::string& path) const {
432 quiche::HttpHeaderBlock headers;
433 headers[":method"] = method;
434 headers[":authority"] = host_;
435 headers[":scheme"] = scheme;
436 headers[":path"] = path;
437 return headers;
438 }
439
ConnectRequestHeaders(const std::string & host_port) const440 quiche::HttpHeaderBlock QuicTestPacketMaker::ConnectRequestHeaders(
441 const std::string& host_port) const {
442 quiche::HttpHeaderBlock headers;
443 headers[":method"] = "CONNECT";
444 headers[":authority"] = host_port;
445 return headers;
446 }
447
GetResponseHeaders(const std::string & status) const448 quiche::HttpHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
449 const std::string& status) const {
450 quiche::HttpHeaderBlock headers;
451 headers[":status"] = status;
452 headers["content-type"] = "text/plain";
453 return headers;
454 }
455
GetResponseHeaders(const std::string & status,const std::string & alt_svc) const456 quiche::HttpHeaderBlock QuicTestPacketMaker::GetResponseHeaders(
457 const std::string& status,
458 const std::string& alt_svc) const {
459 quiche::HttpHeaderBlock headers;
460 headers[":status"] = status;
461 headers["alt-svc"] = alt_svc;
462 headers["content-type"] = "text/plain";
463 return headers;
464 }
465
Reset()466 void QuicTestPacketMaker::Reset() {
467 connection_state_.Reset();
468 }
469
QpackEncodeHeaders(quic::QuicStreamId stream_id,quiche::HttpHeaderBlock headers,size_t * encoded_data_length)470 std::string QuicTestPacketMaker::QpackEncodeHeaders(
471 quic::QuicStreamId stream_id,
472 quiche::HttpHeaderBlock headers,
473 size_t* encoded_data_length) {
474 std::string data;
475
476 std::string encoded_headers =
477 qpack_encoder_.EncodeHeaderList(stream_id, headers, nullptr);
478
479 // Generate HEADERS frame header.
480 const std::string headers_frame_header =
481 quic::HttpEncoder::SerializeHeadersFrameHeader(encoded_headers.size());
482
483 // Add the HEADERS frame header.
484 data += headers_frame_header;
485 // Add the HEADERS frame payload.
486 data += encoded_headers;
487
488 // Compute the total data length.
489 if (encoded_data_length) {
490 *encoded_data_length = data.length();
491 }
492 return data;
493 }
494
FinishPacket(quic::QuicPacketHeader header,quic::QuicFrames frames,std::unique_ptr<quic::QuicStreamFrameDataProducer> data_producer)495 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketMaker::FinishPacket(
496 quic::QuicPacketHeader header,
497 quic::QuicFrames frames,
498 std::unique_ptr<quic::QuicStreamFrameDataProducer> data_producer) {
499 CHECK(builder_);
500 builder_ = nullptr;
501
502 quic::QuicFramer framer(quic::test::SupportedVersions(version_),
503 clock_->Now(), perspective_,
504 quic::kQuicDefaultConnectionIdLength);
505 if (encryption_level_ == quic::ENCRYPTION_INITIAL) {
506 framer.SetInitialObfuscators(perspective_ == quic::Perspective::IS_CLIENT
507 ? header.destination_connection_id
508 : header.source_connection_id);
509 } else {
510 framer.SetEncrypter(
511 encryption_level_,
512 std::make_unique<quic::test::TaggingEncrypter>( // IN-TEST
513 encryption_level_));
514 }
515 if (data_producer != nullptr) {
516 framer.set_data_producer(data_producer.get());
517 }
518 size_t max_plaintext_size = framer.GetMaxPlaintextSize(max_plaintext_size_);
519 size_t packet_size =
520 quic::GetPacketHeaderSize(version_.transport_version, header);
521 size_t frames_size = 0;
522 for (size_t i = 0; i < frames.size(); ++i) {
523 bool first_frame = i == 0;
524 bool last_frame = i == frames.size() - 1;
525 const size_t frame_size = framer.GetSerializedFrameLength(
526 frames[i], max_plaintext_size - packet_size, first_frame, last_frame,
527 header.packet_number_length);
528 packet_size += frame_size;
529 frames_size += frame_size;
530 }
531
532 const size_t min_plaintext_packet_size =
533 quic::QuicPacketCreator::MinPlaintextPacketSize(
534 version_, header.packet_number_length);
535 if (frames_size < min_plaintext_packet_size) {
536 frames.insert(frames.begin(),
537 quic::QuicFrame(quic::QuicPaddingFrame(
538 min_plaintext_packet_size - frames_size)));
539 }
540
541 std::unique_ptr<quic::QuicPacket> packet(quic::test::BuildUnsizedDataPacket(
542 &framer, header, frames, max_plaintext_size));
543 char buffer[quic::kMaxOutgoingPacketSize];
544 size_t encrypted_size =
545 framer.EncryptPayload(encryption_level_, header.packet_number, *packet,
546 buffer, quic::kMaxOutgoingPacketSize);
547 EXPECT_NE(0u, encrypted_size);
548 quic::QuicReceivedPacket encrypted(buffer, encrypted_size, clock_->Now(),
549 false, 0, true, nullptr, 0, false,
550 ecn_codepoint_);
551 if (connection_state_.save_packet_frames) {
552 connection_state_.saved_frames[header.packet_number] = std::move(frames);
553 } else {
554 connection_state_.saved_stream_data.clear();
555 DeleteFrames(&frames);
556 }
557
558 return encrypted.Clone();
559 }
560
GetFirstBidirectionalStreamId() const561 quic::QuicStreamId QuicTestPacketMaker::GetFirstBidirectionalStreamId() const {
562 return quic::QuicUtils::GetFirstBidirectionalStreamId(
563 version_.transport_version, perspective_);
564 }
565
GenerateHttp3PriorityData(spdy::SpdyPriority spdy_priority,quic::QuicStreamId stream_id)566 std::string QuicTestPacketMaker::GenerateHttp3PriorityData(
567 spdy::SpdyPriority spdy_priority,
568 quic::QuicStreamId stream_id) {
569 std::string priority_data;
570 quic::PriorityUpdateFrame priority_update;
571 quic::HttpStreamPriority priority{
572 spdy_priority, quic::HttpStreamPriority::kDefaultIncremental};
573 if (client_priority_uses_incremental_) {
574 priority.incremental = kDefaultPriorityIncremental;
575 }
576
577 if (priority.urgency != quic::HttpStreamPriority::kDefaultUrgency ||
578 priority.incremental != quic::HttpStreamPriority::kDefaultIncremental) {
579 priority_update.priority_field_value =
580 quic::SerializePriorityFieldValue(priority);
581 }
582
583 // Only generate a frame if a non-empty string was generated.
584 if (!priority_update.priority_field_value.empty()) {
585 priority_update.prioritized_element_id = stream_id;
586 priority_data =
587 quic::HttpEncoder::SerializePriorityUpdateFrame(priority_update);
588 }
589
590 return priority_data;
591 }
592
AddPriorityHeader(spdy::SpdyPriority spdy_priority,quiche::HttpHeaderBlock * headers)593 void QuicTestPacketMaker::AddPriorityHeader(spdy::SpdyPriority spdy_priority,
594 quiche::HttpHeaderBlock* headers) {
595 if (use_priority_header_) {
596 quic::HttpStreamPriority priority{
597 spdy_priority, quic::HttpStreamPriority::kDefaultIncremental};
598 if (client_priority_uses_incremental_) {
599 priority.incremental = kDefaultPriorityIncremental;
600 }
601 std::string serialized_priority =
602 quic::SerializePriorityFieldValue(priority);
603 if (!serialized_priority.empty()) {
604 (*headers)[net::kHttp2PriorityHeader] = serialized_priority;
605 }
606 }
607 }
608
QuicTestPacketBuilder(uint64_t packet_number,QuicTestPacketMaker * maker,QuicTestPacketMaker::ConnectionState * connection_state)609 QuicTestPacketBuilder::QuicTestPacketBuilder(
610 uint64_t packet_number,
611 QuicTestPacketMaker* maker,
612 QuicTestPacketMaker::ConnectionState* connection_state)
613 : maker_(maker), connection_state_(connection_state) {
614 CHECK(maker_);
615 InitializeHeader(packet_number);
616 }
617
~QuicTestPacketBuilder()618 QuicTestPacketBuilder::~QuicTestPacketBuilder() {
619 CHECK(!maker_) << "QuicTestPacketBuilder is missing a call to Build()";
620 DeleteFrames(&frames_);
621 }
622
AddPaddingFrame(size_t length)623 QuicTestPacketBuilder& QuicTestPacketBuilder::AddPaddingFrame(size_t length) {
624 quic::QuicPaddingFrame padding_frame =
625 (length > 0) ? quic::QuicPaddingFrame(length) : quic::QuicPaddingFrame();
626 AddFrame(quic::QuicFrame(padding_frame));
627 return *this;
628 }
629
AddPingFrame()630 QuicTestPacketBuilder& QuicTestPacketBuilder::AddPingFrame() {
631 quic::QuicPingFrame ping_frame;
632 AddFrame(quic::QuicFrame(ping_frame));
633 return *this;
634 }
635
AddRetireConnectionIdFrame(uint64_t sequence_number)636 QuicTestPacketBuilder& QuicTestPacketBuilder::AddRetireConnectionIdFrame(
637 uint64_t sequence_number) {
638 auto* retire_cid_frame = new quic::QuicRetireConnectionIdFrame();
639 retire_cid_frame->sequence_number = sequence_number;
640 AddFrame(quic::QuicFrame(retire_cid_frame));
641 return *this;
642 }
643
AddNewConnectionIdFrame(const quic::QuicConnectionId & cid,uint64_t sequence_number,uint64_t retire_prior_to)644 QuicTestPacketBuilder& QuicTestPacketBuilder::AddNewConnectionIdFrame(
645 const quic::QuicConnectionId& cid,
646 uint64_t sequence_number,
647 uint64_t retire_prior_to) {
648 auto* new_cid_frame = new quic::QuicNewConnectionIdFrame();
649 new_cid_frame->connection_id = cid;
650 new_cid_frame->sequence_number = sequence_number;
651 new_cid_frame->retire_prior_to = retire_prior_to;
652 new_cid_frame->stateless_reset_token =
653 quic::QuicUtils::GenerateStatelessResetToken(cid);
654 AddFrame(quic::QuicFrame(new_cid_frame));
655 return *this;
656 }
657
AddMaxStreamsFrame(quic::QuicControlFrameId control_frame_id,quic::QuicStreamCount stream_count,bool unidirectional)658 QuicTestPacketBuilder& QuicTestPacketBuilder::AddMaxStreamsFrame(
659 quic::QuicControlFrameId control_frame_id,
660 quic::QuicStreamCount stream_count,
661 bool unidirectional) {
662 quic::QuicMaxStreamsFrame max_streams_frame(control_frame_id, stream_count,
663 unidirectional);
664 AddFrame(quic::QuicFrame(max_streams_frame));
665 return *this;
666 }
667
AddStreamsBlockedFrame(quic::QuicControlFrameId control_frame_id,quic::QuicStreamCount stream_count,bool unidirectional)668 QuicTestPacketBuilder& QuicTestPacketBuilder::AddStreamsBlockedFrame(
669 quic::QuicControlFrameId control_frame_id,
670 quic::QuicStreamCount stream_count,
671 bool unidirectional) {
672 quic::QuicStreamsBlockedFrame streams_blocked_frame(
673 control_frame_id, stream_count, unidirectional);
674 AddFrame(quic::QuicFrame(streams_blocked_frame));
675 return *this;
676 }
677
AddStreamFrame(quic::QuicStreamId stream_id,bool fin,std::string_view data)678 QuicTestPacketBuilder& QuicTestPacketBuilder::AddStreamFrame(
679 quic::QuicStreamId stream_id,
680 bool fin,
681 std::string_view data) {
682 quic::QuicStreamOffset offset = connection_state_->stream_offsets[stream_id];
683 std::string_view saved_data = connection_state_->SaveStreamData(data);
684 quic::QuicStreamFrame stream_frame(stream_id, fin, offset, saved_data);
685 AddFrame(quic::QuicFrame(stream_frame));
686 connection_state_->stream_offsets[stream_id] += data.length();
687 return *this;
688 }
689
AddAckFrame(uint64_t first_received,uint64_t largest_received,uint64_t smallest_received,std::optional<quic::QuicEcnCounts> ecn)690 QuicTestPacketBuilder& QuicTestPacketBuilder::AddAckFrame(
691 uint64_t first_received,
692 uint64_t largest_received,
693 uint64_t smallest_received,
694 std::optional<quic::QuicEcnCounts> ecn) {
695 auto* ack_frame = new quic::QuicAckFrame;
696 ack_frame->largest_acked = quic::QuicPacketNumber(largest_received);
697 ack_frame->ack_delay_time = quic::QuicTime::Delta::Zero();
698 for (uint64_t i = smallest_received; i <= largest_received; ++i) {
699 ack_frame->received_packet_times.emplace_back(quic::QuicPacketNumber(i),
700 maker_->clock()->Now());
701 }
702 if (largest_received > 0) {
703 DCHECK_GE(largest_received, first_received);
704 ack_frame->packets.AddRange(quic::QuicPacketNumber(first_received),
705 quic::QuicPacketNumber(largest_received + 1));
706 }
707 ack_frame->ecn_counters = ecn;
708 AddFrame(quic::QuicFrame(ack_frame));
709 return *this;
710 }
711
AddMessageFrame(std::string_view data)712 QuicTestPacketBuilder& QuicTestPacketBuilder::AddMessageFrame(
713 std::string_view data) {
714 auto* message_frame = new quic::QuicMessageFrame(
715 /*message_id=*/0, quiche::QuicheMemSlice(quiche::QuicheBuffer::Copy(
716 quiche::SimpleBufferAllocator::Get(), data)));
717 AddFrame(quic::QuicFrame(message_frame));
718 return *this;
719 }
720
AddRstStreamFrame(quic::QuicStreamId stream_id,quic::QuicRstStreamErrorCode error_code)721 QuicTestPacketBuilder& QuicTestPacketBuilder::AddRstStreamFrame(
722 quic::QuicStreamId stream_id,
723 quic::QuicRstStreamErrorCode error_code) {
724 auto* rst_stream_frame = new quic::QuicRstStreamFrame(
725 1, stream_id, error_code, connection_state_->stream_offsets[stream_id]);
726 AddFrame(quic::QuicFrame(rst_stream_frame));
727 return *this;
728 }
729
AddConnectionCloseFrame(quic::QuicErrorCode quic_error,const std::string & quic_error_details,uint64_t frame_type)730 QuicTestPacketBuilder& QuicTestPacketBuilder::AddConnectionCloseFrame(
731 quic::QuicErrorCode quic_error,
732 const std::string& quic_error_details,
733 uint64_t frame_type) {
734 auto* close_frame = new quic::QuicConnectionCloseFrame(
735 maker_->version().transport_version, quic_error, quic::NO_IETF_QUIC_ERROR,
736 quic_error_details, frame_type);
737 AddFrame(quic::QuicFrame(close_frame));
738 return *this;
739 }
740
AddGoAwayFrame(quic::QuicErrorCode error_code,std::string reason_phrase)741 QuicTestPacketBuilder& QuicTestPacketBuilder::AddGoAwayFrame(
742 quic::QuicErrorCode error_code,
743 std::string reason_phrase) {
744 auto* goaway_frame = new quic::QuicGoAwayFrame();
745 goaway_frame->error_code = error_code;
746 goaway_frame->last_good_stream_id = 0;
747 goaway_frame->reason_phrase = reason_phrase;
748 AddFrame(quic::QuicFrame(goaway_frame));
749 return *this;
750 }
751
AddPathResponseFrame()752 QuicTestPacketBuilder& QuicTestPacketBuilder::AddPathResponseFrame() {
753 quic::test::MockRandom rand(0);
754 quic::QuicPathFrameBuffer payload;
755 rand.RandBytes(payload.data(), payload.size());
756 auto path_response_frame = quic::QuicPathResponseFrame(0, payload);
757 AddFrame(quic::QuicFrame(path_response_frame));
758 return *this;
759 }
760
AddPathChallengeFrame()761 QuicTestPacketBuilder& QuicTestPacketBuilder::AddPathChallengeFrame() {
762 quic::test::MockRandom rand(0);
763 quic::QuicPathFrameBuffer payload;
764 rand.RandBytes(payload.data(), payload.size());
765 auto path_challenge_frame = quic::QuicPathChallengeFrame(0, payload);
766 AddFrame(quic::QuicFrame(path_challenge_frame));
767 return *this;
768 }
769
AddStopSendingFrame(quic::QuicStreamId stream_id,quic::QuicRstStreamErrorCode error_code)770 QuicTestPacketBuilder& QuicTestPacketBuilder::AddStopSendingFrame(
771 quic::QuicStreamId stream_id,
772 quic::QuicRstStreamErrorCode error_code) {
773 auto stop_sending_frame =
774 quic::QuicStopSendingFrame(1, stream_id, error_code);
775 AddFrame(quic::QuicFrame(stop_sending_frame));
776 return *this;
777 }
778
AddCryptoFrame(quic::EncryptionLevel level,quic::QuicStreamOffset offset,const quic::QuicData & data)779 QuicTestPacketBuilder& QuicTestPacketBuilder::AddCryptoFrame(
780 quic::EncryptionLevel level,
781 quic::QuicStreamOffset offset,
782 const quic::QuicData& data) {
783 if (!data_producer_) {
784 data_producer_ =
785 std::make_unique<quic::test::SimpleDataProducer>(); // IN-TEST
786 }
787 data_producer_->SaveCryptoData(level, offset, data.AsStringPiece());
788 auto* crypto_frame = new quic::QuicCryptoFrame(level, offset, data.length());
789 AddFrame(quic::QuicFrame(crypto_frame));
790 return *this;
791 }
792
AddFrame(quic::QuicFrame frame)793 QuicTestPacketBuilder& QuicTestPacketBuilder::AddFrame(quic::QuicFrame frame) {
794 CHECK(maker_);
795 frames_.push_back(std::move(frame));
796 DVLOG(1) << "Adding frame: " << frames_.back();
797 return *this;
798 }
799
AddFrameWithCoalescing(const quic::QuicFrame & frame)800 QuicTestPacketBuilder& QuicTestPacketBuilder::AddFrameWithCoalescing(
801 const quic::QuicFrame& frame) {
802 if (frames_.empty()) {
803 return AddFrame(frame);
804 }
805 if (frame.type != quic::STREAM_FRAME ||
806 frames_.back().type != quic::STREAM_FRAME) {
807 return AddFrame(frame);
808 }
809
810 // Make sure they are congruent data segments in the stream.
811 const quic::QuicStreamFrame* new_frame = &frame.stream_frame;
812 quic::QuicStreamFrame* previous_frame = &frames_.back().stream_frame;
813 if (new_frame->stream_id != previous_frame->stream_id ||
814 new_frame->offset !=
815 previous_frame->offset + previous_frame->data_length) {
816 return AddFrame(frame);
817 }
818
819 // Extend the data buffer to include the data from both frames (into a copy
820 // buffer). This doesn't attempt to limit coalescing to a particular packet
821 // size limit and may need to be updated if a test comes along that
822 // retransmits enough stream data to span multiple packets.
823 std::string data(previous_frame->data_buffer, previous_frame->data_length);
824 data += std::string(new_frame->data_buffer, new_frame->data_length);
825 connection_state_->saved_stream_data.push_back(
826 std::make_unique<std::string>(data));
827 std::string_view saved_data = *connection_state_->saved_stream_data.back();
828 previous_frame->data_buffer = saved_data.data();
829 previous_frame->data_length = saved_data.length();
830
831 // Copy the fin state from the last frame.
832 previous_frame->fin = new_frame->fin;
833
834 return *this;
835 }
836
AddPacketRetransmission(uint64_t packet_number,base::RepeatingCallback<bool (const quic::QuicFrame &)> filter)837 QuicTestPacketBuilder& QuicTestPacketBuilder::AddPacketRetransmission(
838 uint64_t packet_number,
839 base::RepeatingCallback<bool(const quic::QuicFrame&)> filter) {
840 for (auto frame :
841 connection_state_->saved_frames[quic::QuicPacketNumber(packet_number)]) {
842 if (!filter || filter.Run(frame)) {
843 AddFrameWithCoalescing(frame);
844 }
845 }
846 return *this;
847 }
848
Build()849 std::unique_ptr<quic::QuicReceivedPacket> QuicTestPacketBuilder::Build() {
850 CHECK(maker_);
851 QuicTestPacketMaker* maker = maker_;
852 maker_ = nullptr;
853 return maker->FinishPacket(std::move(header_), std::move(frames_),
854 std::move(data_producer_));
855 }
856
MaybeAddHttp3SettingsFrames()857 QuicTestPacketBuilder& QuicTestPacketBuilder::MaybeAddHttp3SettingsFrames() {
858 quic::QuicStreamId stream_id =
859 quic::QuicUtils::GetFirstUnidirectionalStreamId(
860 maker_->version().transport_version, maker_->perspective());
861
862 // If the control stream has already been written to, do nothing.
863 if (connection_state_->stream_offsets[stream_id] != 0) {
864 return *this;
865 }
866
867 // A stream frame containing stream type will be written on the control
868 // stream first.
869 std::string type(1, 0x00);
870 std::string settings_data = GenerateHttp3SettingsData();
871 std::string grease_data = GenerateHttp3GreaseData();
872
873 // The type and the SETTINGS frame may be sent in multiple QUIC STREAM
874 // frames.
875 std::string data = type + settings_data + grease_data;
876
877 AddStreamFrame(stream_id, false, data);
878 return *this;
879 }
880
GenerateHttp3SettingsData() const881 std::string QuicTestPacketBuilder::GenerateHttp3SettingsData() const {
882 quic::SettingsFrame settings;
883 settings.values[quic::SETTINGS_MAX_FIELD_SECTION_SIZE] =
884 kQuicMaxHeaderListSize;
885 settings.values[quic::SETTINGS_QPACK_MAX_TABLE_CAPACITY] =
886 quic::kDefaultQpackMaxDynamicTableCapacity;
887 settings.values[quic::SETTINGS_QPACK_BLOCKED_STREAMS] =
888 quic::kDefaultMaximumBlockedStreams;
889 settings.values[quic::SETTINGS_H3_DATAGRAM] = 1;
890 // Greased setting.
891 settings.values[0x40] = 20;
892 return quic::HttpEncoder::SerializeSettingsFrame(settings);
893 }
894
GenerateHttp3GreaseData() const895 std::string QuicTestPacketBuilder::GenerateHttp3GreaseData() const {
896 return quic::HttpEncoder::SerializeGreasingFrame();
897 }
898
InitializeHeader(uint64_t packet_number)899 void QuicTestPacketBuilder::InitializeHeader(uint64_t packet_number) {
900 header_.destination_connection_id = DestinationConnectionId();
901 header_.destination_connection_id_included = quic::CONNECTION_ID_PRESENT;
902 header_.source_connection_id = SourceConnectionId();
903 header_.source_connection_id_included = quic::CONNECTION_ID_PRESENT;
904 header_.reset_flag = false;
905 header_.version_flag = ShouldIncludeVersion();
906 header_.form = header_.version_flag ? quic::IETF_QUIC_LONG_HEADER_PACKET
907 : quic::IETF_QUIC_SHORT_HEADER_PACKET;
908 header_.long_packet_type = maker_->long_header_type();
909 header_.packet_number_length = quic::PACKET_1BYTE_PACKET_NUMBER;
910 header_.packet_number = quic::QuicPacketNumber(packet_number);
911 if (header_.version_flag) {
912 if (maker_->long_header_type() == quic::INITIAL) {
913 header_.retry_token_length_length =
914 quiche::VARIABLE_LENGTH_INTEGER_LENGTH_1;
915 }
916 header_.length_length = quiche::VARIABLE_LENGTH_INTEGER_LENGTH_2;
917 }
918 }
919
DestinationConnectionId() const920 quic::QuicConnectionId QuicTestPacketBuilder::DestinationConnectionId() const {
921 if (maker_->perspective() == quic::Perspective::IS_SERVER) {
922 return quic::EmptyQuicConnectionId();
923 }
924 return maker_->connection_id();
925 }
926
SourceConnectionId() const927 quic::QuicConnectionId QuicTestPacketBuilder::SourceConnectionId() const {
928 if (maker_->perspective() == quic::Perspective::IS_CLIENT) {
929 return quic::EmptyQuicConnectionId();
930 }
931 return maker_->connection_id();
932 }
933
ShouldIncludeVersion() const934 bool QuicTestPacketBuilder::ShouldIncludeVersion() const {
935 return maker_->encryption_level() < quic::ENCRYPTION_FORWARD_SECURE;
936 }
937
938 } // namespace net::test
939