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 // Provides a simple interface for QUIC tests to create a variety of packets. 6 7 #ifndef NET_QUIC_QUIC_TEST_PACKET_MAKER_H_ 8 #define NET_QUIC_QUIC_TEST_PACKET_MAKER_H_ 9 10 #include <stddef.h> 11 #include <sys/types.h> 12 13 #include <memory> 14 #include <optional> 15 #include <string> 16 #include <vector> 17 18 #include "base/memory/raw_ptr.h" 19 #include "net/base/request_priority.h" 20 #include "net/third_party/quiche/src/quiche/quic/core/http/http_encoder.h" 21 #include "net/third_party/quiche/src/quiche/quic/core/qpack/qpack_encoder.h" 22 #include "net/third_party/quiche/src/quiche/quic/core/quic_clock.h" 23 #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h" 24 #include "net/third_party/quiche/src/quiche/quic/core/quic_stream_frame_data_producer.h" 25 #include "net/third_party/quiche/src/quiche/quic/core/quic_types.h" 26 #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h" 27 #include "net/third_party/quiche/src/quiche/quic/test_tools/mock_random.h" 28 #include "net/third_party/quiche/src/quiche/quic/test_tools/qpack/qpack_test_utils.h" 29 #include "net/third_party/quiche/src/quiche/quic/test_tools/simple_data_producer.h" 30 31 namespace net::test { 32 33 class QuicTestPacketMaker { 34 public: 35 // |client_priority_uses_incremental| affects the output of any method that 36 // includes HTTP3 priority data. The protocol default is to omit the 37 // incremental flag in the priority data but HTTP streams may enable it 38 // if the client supports incremental streams. 39 QuicTestPacketMaker(quic::ParsedQuicVersion version, 40 quic::QuicConnectionId connection_id, 41 const quic::QuicClock* clock, 42 const std::string& host, 43 quic::Perspective perspective, 44 bool client_priority_uses_incremental = false, 45 bool use_priority_header = false); 46 47 QuicTestPacketMaker(const QuicTestPacketMaker&) = delete; 48 QuicTestPacketMaker& operator=(const QuicTestPacketMaker&) = delete; 49 50 ~QuicTestPacketMaker(); 51 52 void set_hostname(const std::string& host); 53 set_use_priority_header(const bool use_priority_header)54 void set_use_priority_header(const bool use_priority_header) { 55 use_priority_header_ = use_priority_header; 56 } 57 set_connection_id(const quic::QuicConnectionId & connection_id)58 void set_connection_id(const quic::QuicConnectionId& connection_id) { 59 connection_id_ = connection_id; 60 } 61 62 std::unique_ptr<quic::QuicReceivedPacket> MakeConnectivityProbingPacket( 63 uint64_t num); 64 65 std::unique_ptr<quic::QuicReceivedPacket> MakePingPacket(uint64_t num); 66 67 std::unique_ptr<quic::QuicReceivedPacket> MakeRetireConnectionIdPacket( 68 uint64_t num, 69 uint64_t sequence_number); 70 71 std::unique_ptr<quic::QuicReceivedPacket> MakeNewConnectionIdPacket( 72 uint64_t num, 73 const quic::QuicConnectionId& cid, 74 uint64_t sequence_number, 75 uint64_t retire_prior_to); 76 77 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndNewConnectionIdPacket( 78 uint64_t num, 79 uint64_t largest_received, 80 uint64_t smallest_received, 81 const quic::QuicConnectionId& cid, 82 uint64_t sequence_number, 83 uint64_t retire_prior_to); 84 85 std::unique_ptr<quic::QuicReceivedPacket> MakeDummyCHLOPacket( 86 uint64_t packet_num); 87 88 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndPingPacket( 89 uint64_t num, 90 uint64_t largest_received, 91 uint64_t smallest_received); 92 93 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRetireConnectionIdPacket( 94 uint64_t num, 95 uint64_t largest_received, 96 uint64_t smallest_received, 97 uint64_t sequence_number); 98 99 std::unique_ptr<quic::QuicReceivedPacket> 100 MakeRetransmissionAndRetireConnectionIdPacket( 101 uint64_t num, 102 const std::vector<uint64_t>& original_packet_numbers, 103 uint64_t sequence_number); 104 105 std::unique_ptr<quic::QuicReceivedPacket> MakeStreamsBlockedPacket( 106 uint64_t num, 107 quic::QuicStreamCount stream_count, 108 bool unidirectional); 109 110 std::unique_ptr<quic::QuicReceivedPacket> MakeMaxStreamsPacket( 111 uint64_t num, 112 quic::QuicStreamCount stream_count, 113 bool unidirectional); 114 115 std::unique_ptr<quic::QuicReceivedPacket> MakeRstPacket( 116 uint64_t num, 117 quic::QuicStreamId stream_id, 118 quic::QuicRstStreamErrorCode error_code); 119 120 std::unique_ptr<quic::QuicReceivedPacket> MakeRstPacket( 121 uint64_t num, 122 quic::QuicStreamId stream_id, 123 quic::QuicRstStreamErrorCode error_code, 124 bool include_stop_sending_if_v99); 125 126 std::unique_ptr<quic::QuicReceivedPacket> MakeRstAndDataPacket( 127 uint64_t num, 128 quic::QuicStreamId rst_stream_id, 129 quic::QuicRstStreamErrorCode rst_error_code, 130 quic::QuicStreamId data_stream_id, 131 std::string_view data); 132 133 std::unique_ptr<quic::QuicReceivedPacket> MakeRetransmissionRstAndDataPacket( 134 const std::vector<uint64_t>& original_packet_numbers, 135 uint64_t num, 136 quic::QuicStreamId rst_stream_id, 137 quic::QuicRstStreamErrorCode rst_error_code, 138 quic::QuicStreamId data_stream_id, 139 std::string_view data, 140 uint64_t retransmit_frame_count = 0); 141 142 std::unique_ptr<quic::QuicReceivedPacket> MakeDataAndRstPacket( 143 uint64_t num, 144 quic::QuicStreamId data_stream_id, 145 std::string_view data, 146 quic::QuicStreamId rst_stream_id, 147 quic::QuicRstStreamErrorCode rst_error_code); 148 149 std::unique_ptr<quic::QuicReceivedPacket> MakeDataRstAndAckPacket( 150 uint64_t num, 151 quic::QuicStreamId data_stream_id, 152 std::string_view data, 153 quic::QuicStreamId rst_stream_id, 154 quic::QuicRstStreamErrorCode rst_error_code, 155 uint64_t largest_received, 156 uint64_t smallest_received); 157 158 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket( 159 uint64_t num, 160 quic::QuicStreamId stream_id, 161 quic::QuicRstStreamErrorCode error_code, 162 uint64_t largest_received, 163 uint64_t smallest_received); 164 165 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRstPacket( 166 uint64_t num, 167 quic::QuicStreamId stream_id, 168 quic::QuicRstStreamErrorCode error_code, 169 uint64_t largest_received, 170 uint64_t smallest_received, 171 bool include_stop_sending_if_v99); 172 173 std::unique_ptr<quic::QuicReceivedPacket> MakeRstAckAndConnectionClosePacket( 174 uint64_t num, 175 quic::QuicStreamId stream_id, 176 quic::QuicRstStreamErrorCode error_code, 177 uint64_t largest_received, 178 uint64_t smallest_received, 179 quic::QuicErrorCode quic_error, 180 const std::string& quic_error_details); 181 182 std::unique_ptr<quic::QuicReceivedPacket> MakeRstAckAndDataPacket( 183 uint64_t num, 184 quic::QuicStreamId stream_id, 185 quic::QuicRstStreamErrorCode error_code, 186 uint64_t largest_received, 187 uint64_t smallest_received, 188 quic::QuicStreamId data_id, 189 bool fin, 190 std::string_view data); 191 192 std::unique_ptr<quic::QuicReceivedPacket> MakeAckDataAndRst( 193 uint64_t num, 194 quic::QuicStreamId stream_id, 195 quic::QuicRstStreamErrorCode error_code, 196 uint64_t largest_received, 197 uint64_t smallest_received, 198 quic::QuicStreamId data_id, 199 bool fin, 200 std::string_view data); 201 202 std::unique_ptr<quic::QuicReceivedPacket> MakeAckRstAndDataPacket( 203 uint64_t num, 204 quic::QuicStreamId stream_id, 205 quic::QuicRstStreamErrorCode error_code, 206 uint64_t largest_received, 207 uint64_t smallest_received, 208 quic::QuicStreamId data_id, 209 bool fin, 210 std::string_view data); 211 212 std::unique_ptr<quic::QuicReceivedPacket> MakeRstAndConnectionClosePacket( 213 uint64_t num, 214 quic::QuicStreamId stream_id, 215 quic::QuicRstStreamErrorCode error_code, 216 quic::QuicErrorCode quic_error, 217 const std::string& quic_error_details); 218 219 std::unique_ptr<quic::QuicReceivedPacket> MakeDataRstAndConnectionClosePacket( 220 uint64_t num, 221 quic::QuicStreamId data_stream_id, 222 std::string_view data, 223 quic::QuicStreamId rst_stream_id, 224 quic::QuicRstStreamErrorCode error_code, 225 quic::QuicErrorCode quic_error, 226 const std::string& quic_error_details); 227 228 std::unique_ptr<quic::QuicReceivedPacket> 229 MakeDataRstAckAndConnectionClosePacket( 230 uint64_t num, 231 quic::QuicStreamId data_stream_id, 232 std::string_view data, 233 quic::QuicStreamId rst_stream_id, 234 quic::QuicRstStreamErrorCode error_code, 235 uint64_t largest_received, 236 uint64_t smallest_received, 237 quic::QuicErrorCode quic_error, 238 const std::string& quic_error_details); 239 240 std::unique_ptr<quic::QuicReceivedPacket> 241 MakeDataRstAckAndConnectionClosePacket( 242 uint64_t num, 243 quic::QuicStreamId data_stream_id, 244 std::string_view data, 245 quic::QuicStreamId rst_stream_id, 246 quic::QuicRstStreamErrorCode error_code, 247 uint64_t largest_received, 248 uint64_t smallest_received, 249 quic::QuicErrorCode quic_error, 250 const std::string& quic_error_details, 251 uint64_t frame_type); 252 253 std::unique_ptr<quic::QuicReceivedPacket> MakeStopSendingPacket( 254 uint64_t num, 255 quic::QuicStreamId stream_id, 256 quic::QuicRstStreamErrorCode error_code); 257 258 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndConnectionClosePacket( 259 uint64_t num, 260 uint64_t largest_received, 261 uint64_t smallest_received, 262 quic::QuicErrorCode quic_error, 263 const std::string& quic_error_details, 264 uint64_t frame_type); 265 266 std::unique_ptr<quic::QuicReceivedPacket> MakeConnectionClosePacket( 267 uint64_t num, 268 quic::QuicErrorCode quic_error, 269 const std::string& quic_error_details); 270 271 std::unique_ptr<quic::QuicReceivedPacket> MakeGoAwayPacket( 272 uint64_t num, 273 quic::QuicErrorCode error_code, 274 std::string reason_phrase); 275 276 std::unique_ptr<quic::QuicReceivedPacket> MakeAckPacket( 277 uint64_t packet_number, 278 uint64_t largest_received, 279 uint64_t smallest_received); 280 281 std::unique_ptr<quic::QuicReceivedPacket> MakeAckPacket( 282 uint64_t packet_number, 283 uint64_t first_received, 284 uint64_t largest_received, 285 uint64_t smallest_received, 286 std::optional<quic::QuicEcnCounts> ecn = std::nullopt); 287 288 std::unique_ptr<quic::QuicReceivedPacket> MakeDataPacket( 289 uint64_t packet_number, 290 quic::QuicStreamId stream_id, 291 bool fin, 292 std::string_view data); 293 294 std::unique_ptr<quic::QuicReceivedPacket> MakeDatagramPacket( 295 uint64_t packet_number, 296 std::string_view datagram); 297 298 std::unique_ptr<quic::QuicReceivedPacket> MakeDatagramPacket( 299 uint64_t packet_number, 300 std::vector<std::string> datagrams); 301 302 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndDataPacket( 303 uint64_t packet_number, 304 quic::QuicStreamId stream_id, 305 uint64_t largest_received, 306 uint64_t smallest_received, 307 bool fin, 308 std::string_view data); 309 310 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndDatagramPacket( 311 uint64_t packet_number, 312 uint64_t largest_received, 313 uint64_t smallest_received, 314 std::string_view data); 315 316 std::unique_ptr<quic::QuicReceivedPacket> MakeAckRetransmissionAndDataPacket( 317 uint64_t packet_number, 318 const std::vector<uint64_t>& original_packet_numbers, 319 quic::QuicStreamId stream_id, 320 uint64_t largest_received, 321 uint64_t smallest_received, 322 bool fin, 323 std::string_view data); 324 325 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndRetransmissionPacket( 326 uint64_t packet_number, 327 uint64_t first_received, 328 uint64_t largest_received, 329 uint64_t smallest_received, 330 const std::vector<uint64_t>& original_packet_numbers); 331 332 std::unique_ptr<quic::QuicReceivedPacket> 333 MakeRequestHeadersAndMultipleDataFramesPacket( 334 uint64_t packet_number, 335 quic::QuicStreamId stream_id, 336 bool fin, 337 spdy::SpdyPriority spdy_priority, 338 spdy::Http2HeaderBlock headers, 339 size_t* spdy_headers_frame_length, 340 const std::vector<std::string>& data_writes); 341 342 // If |spdy_headers_frame_length| is non-null, it will be set to the size of 343 // the SPDY headers frame created for this packet. 344 std::unique_ptr<quic::QuicReceivedPacket> MakeRequestHeadersPacket( 345 uint64_t packet_number, 346 quic::QuicStreamId stream_id, 347 bool fin, 348 spdy::SpdyPriority spdy_priority, 349 spdy::Http2HeaderBlock headers, 350 size_t* spdy_headers_frame_length, 351 bool should_include_priority_frame = true); 352 353 std::unique_ptr<quic::QuicReceivedPacket> 354 MakeRetransmissionAndRequestHeadersPacket( 355 const std::vector<uint64_t>& original_packet_numbers, 356 uint64_t packet_number, 357 quic::QuicStreamId stream_id, 358 bool fin, 359 spdy::SpdyPriority spdy_priority, 360 spdy::Http2HeaderBlock headers, 361 size_t* spdy_headers_frame_length); 362 363 std::unique_ptr<quic::QuicReceivedPacket> MakeRequestHeadersAndRstPacket( 364 uint64_t packet_number, 365 quic::QuicStreamId stream_id, 366 bool fin, 367 spdy::SpdyPriority spdy_priority, 368 spdy::Http2HeaderBlock headers, 369 size_t* spdy_headers_frame_length, 370 quic::QuicRstStreamErrorCode error_code); 371 372 // If |spdy_headers_frame_length| is non-null, it will be set to the size of 373 // the SPDY headers frame created for this packet. 374 std::unique_ptr<quic::QuicReceivedPacket> MakeResponseHeadersPacket( 375 uint64_t packet_number, 376 quic::QuicStreamId stream_id, 377 bool fin, 378 spdy::Http2HeaderBlock headers, 379 size_t* spdy_headers_frame_length); 380 381 // Creates a packet containing the initial SETTINGS frame, and saves the 382 // headers stream offset into |offset|. 383 std::unique_ptr<quic::QuicReceivedPacket> MakeInitialSettingsPacket( 384 uint64_t packet_number); 385 386 std::unique_ptr<quic::QuicReceivedPacket> MakePriorityPacket( 387 uint64_t packet_number, 388 quic::QuicStreamId id, 389 spdy::SpdyPriority spdy_priority); 390 391 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndPriorityPacket( 392 uint64_t packet_number, 393 uint64_t largest_received, 394 uint64_t smallest_received, 395 quic::QuicStreamId id, 396 spdy::SpdyPriority spdy_priority); 397 398 std::unique_ptr<quic::QuicReceivedPacket> MakeRetransmissionPacket( 399 uint64_t original_packet_number, 400 uint64_t new_packet_number); 401 402 std::unique_ptr<quic::QuicReceivedPacket> MakeCombinedRetransmissionPacket( 403 const std::vector<uint64_t>& original_packet_numbers, 404 uint64_t new_packet_number); 405 406 std::unique_ptr<quic::QuicReceivedPacket> MakeAckAndPriorityUpdatePacket( 407 uint64_t packet_number, 408 uint64_t largest_received, 409 uint64_t smallest_received, 410 quic::QuicStreamId id, 411 spdy::SpdyPriority spdy_priority); 412 413 std::unique_ptr<quic::QuicEncryptedPacket> MakeStatelessResetPacket(); 414 415 // Removes all stream frames associated with |stream_id|. 416 void RemoveSavedStreamFrames(quic::QuicStreamId stream_id); 417 418 void SetEncryptionLevel(quic::EncryptionLevel level); 419 420 spdy::Http2HeaderBlock GetRequestHeaders(const std::string& method, 421 const std::string& scheme, 422 const std::string& path) const; 423 424 spdy::Http2HeaderBlock ConnectRequestHeaders( 425 const std::string& host_port) const; 426 427 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status) const; 428 429 spdy::Http2HeaderBlock GetResponseHeaders(const std::string& status, 430 const std::string& alt_svc) const; 431 432 void Reset(); 433 stream_offset(quic::QuicStreamId stream_id)434 quic::QuicStreamOffset stream_offset(quic::QuicStreamId stream_id) { 435 return stream_offsets_[stream_id]; 436 } 437 set_save_packet_frames(bool save_packet_frames)438 void set_save_packet_frames(bool save_packet_frames) { 439 save_packet_frames_ = save_packet_frames; 440 } 441 442 std::string QpackEncodeHeaders(quic::QuicStreamId stream_id, 443 spdy::Http2HeaderBlock headers, 444 size_t* encoded_data_length); 445 set_ecn_codepoint(quic::QuicEcnCodepoint ecn)446 void set_ecn_codepoint(quic::QuicEcnCodepoint ecn) { ecn_codepoint_ = ecn; } 447 448 private: 449 // Initialize header of next packet to build. 450 void InitializeHeader(uint64_t packet_number); 451 452 // Add frames to current packet. 453 void AddQuicPaddingFrame(); 454 void AddQuicPingFrame(); 455 void AddQuicRetireConnectionIdFrame(uint64_t sequence_number); 456 void AddQuicNewConnectionIdFrame(const quic::QuicConnectionId& cid, 457 uint64_t sequence_number, 458 uint64_t retire_prior_to, 459 quic::StatelessResetToken reset_token); 460 void AddQuicMaxStreamsFrame(quic::QuicControlFrameId control_frame_id, 461 quic::QuicStreamCount stream_count, 462 bool unidirectional); 463 void AddQuicStreamsBlockedFrame(quic::QuicControlFrameId control_frame_id, 464 quic::QuicStreamCount stream_count, 465 bool unidirectional); 466 // Use and increase stream's current offset. 467 void AddQuicStreamFrame(quic::QuicStreamId stream_id, 468 bool fin, 469 std::string_view data); 470 // Use |offset| and do not change stream's current offset. 471 void AddQuicStreamFrameWithOffset(quic::QuicStreamId stream_id, 472 bool fin, 473 quic::QuicStreamOffset offset, 474 std::string_view data); 475 void AddQuicAckFrame(uint64_t largest_received, uint64_t smallest_received); 476 void AddQuicAckFrame(uint64_t first_received, 477 uint64_t largest_received, 478 uint64_t smallest_received, 479 std::optional<quic::QuicEcnCounts> ecn = std::nullopt); 480 void AddQuicMessageFrame(std::string_view data); 481 void AddQuicRstStreamFrame(quic::QuicStreamId stream_id, 482 quic::QuicRstStreamErrorCode error_code); 483 void AddQuicConnectionCloseFrame(quic::QuicErrorCode quic_error, 484 const std::string& quic_error_details); 485 void AddQuicConnectionCloseFrame(quic::QuicErrorCode quic_error, 486 const std::string& quic_error_details, 487 uint64_t frame_type); 488 void AddQuicGoAwayFrame(quic::QuicErrorCode error_code, 489 std::string reason_phrase); 490 void AddQuicPathResponseFrame(); 491 void AddQuicPathChallengeFrame(); 492 void AddQuicStopSendingFrame(quic::QuicStreamId stream_id, 493 quic::QuicRstStreamErrorCode error_code); 494 void AddQuicCryptoFrame(quic::EncryptionLevel level, 495 quic::QuicStreamOffset offset, 496 quic::QuicPacketLength data_length); 497 void AddPriorityHeader(spdy::SpdyPriority spdy_priority, 498 spdy::Http2HeaderBlock* headers); 499 500 // Build packet using |header_|, |frames_|, and |data_producer_|, 501 // and clear |frames_| and |data_producer_| afterwards. 502 std::unique_ptr<quic::QuicReceivedPacket> BuildPacket(); 503 504 // Build packet using |header_|, |frames|, and |data_producer|. 505 std::unique_ptr<quic::QuicReceivedPacket> BuildPacketImpl( 506 const quic::QuicFrames& frames, 507 quic::QuicStreamFrameDataProducer* data_producer); 508 509 bool ShouldIncludeVersion() const; 510 511 quic::QuicConnectionId DestinationConnectionId() const; 512 quic::QuicConnectionId SourceConnectionId() const; 513 514 quic::QuicStreamId GetFirstBidirectionalStreamId() const; 515 516 std::string GenerateHttp3SettingsData(); 517 std::string GenerateHttp3PriorityData(spdy::SpdyPriority spdy_priority, 518 quic::QuicStreamId stream_id); 519 std::string GenerateHttp3GreaseData(); 520 521 void MaybeAddHttp3SettingsFrames(); 522 bool MaybeCoalesceStreamFrame(const quic::QuicFrame& frame); 523 524 // Parameters used throughout the lifetime of the class. 525 quic::ParsedQuicVersion version_; 526 quic::QuicConnectionId connection_id_; 527 raw_ptr<const quic::QuicClock> clock_; // Not owned. 528 std::string host_; 529 quic::NoopDecoderStreamErrorDelegate decoder_stream_error_delegate_; 530 quic::test::NoopQpackStreamSenderDelegate encoder_stream_sender_delegate_; 531 quic::QpackEncoder qpack_encoder_; 532 quic::test::MockRandom random_generator_; 533 std::map<quic::QuicStreamId, quic::QuicStreamOffset> stream_offsets_; 534 quic::Perspective perspective_; 535 quic::EncryptionLevel encryption_level_ = quic::ENCRYPTION_FORWARD_SECURE; 536 quic::QuicLongHeaderType long_header_type_ = quic::INVALID_PACKET_TYPE; 537 538 // The value of incremental flag in generated priority headers. 539 bool client_priority_uses_incremental_; 540 541 // Add the priority header to outbound requests 542 bool use_priority_header_; 543 544 // Save a copy of stream frame data that QuicStreamFrame objects can refer to. 545 std::vector<std::unique_ptr<std::string>> saved_stream_data_; 546 // If |save_packet_frames_| is true, save generated packets in 547 // |saved_frames_|, allowing retransmission packets to be built. 548 bool save_packet_frames_ = false; 549 std::map<quic::QuicPacketNumber, quic::QuicFrames> saved_frames_; 550 551 // State necessary for building the current packet. 552 quic::QuicPacketHeader header_; 553 quic::QuicFrames frames_; 554 std::unique_ptr<quic::test::SimpleDataProducer> data_producer_; 555 556 // Explicit Congestion Notification (ECN) codepoint to use when making 557 // packets. 558 quic::QuicEcnCodepoint ecn_codepoint_ = quic::ECN_NOT_ECT; 559 }; 560 561 } // namespace net::test 562 563 #endif // NET_QUIC_QUIC_TEST_PACKET_MAKER_H_ 564