• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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