Move connectivity probing related code from QuicFramer to QuicPacketCreator.
QuicPacketCreator has access to debug_delegate_, which helps log on path challenge frames.
gfe-relnote: protected by disabled v99 flag.
PiperOrigin-RevId: 273405309
Change-Id: I5f7805e0254fcaa417cababc0af0681bf8901e26
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index e7f5185..1a2ca6f 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -5,10 +5,12 @@
#include "net/third_party/quiche/src/quic/core/quic_packet_creator.h"
#include <algorithm>
+#include <cstddef>
#include <cstdint>
#include <string>
#include "net/third_party/quiche/src/quic/core/crypto/crypto_protocol.h"
+#include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h"
#include "net/third_party/quiche/src/quic/core/quic_connection_id.h"
#include "net/third_party/quiche/src/quic/core/quic_constants.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"
@@ -700,7 +702,7 @@
<< header;
std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- size_t length = framer_->BuildConnectivityProbingPacket(
+ size_t length = BuildConnectivityProbingPacket(
header, buffer.get(), max_plaintext_size_, packet_.encryption_level);
DCHECK(length);
@@ -734,7 +736,7 @@
QUIC_DVLOG(2) << ENDPOINT << "Serializing path challenge packet " << header;
std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- size_t length = framer_->BuildPaddedPathChallengePacket(
+ size_t length = BuildPaddedPathChallengePacket(
header, buffer.get(), max_plaintext_size_, payload, random_,
packet_.encryption_level);
DCHECK(length);
@@ -770,9 +772,9 @@
QUIC_DVLOG(2) << ENDPOINT << "Serializing path response packet " << header;
std::unique_ptr<char[]> buffer(new char[kMaxOutgoingPacketSize]);
- size_t length = framer_->BuildPathResponsePacket(
- header, buffer.get(), max_plaintext_size_, payloads, is_padded,
- packet_.encryption_level);
+ size_t length =
+ BuildPathResponsePacket(header, buffer.get(), max_plaintext_size_,
+ payloads, is_padded, packet_.encryption_level);
DCHECK(length);
const size_t encrypted_length = framer_->EncryptInPlace(
@@ -791,6 +793,92 @@
return serialize_packet;
}
+size_t QuicPacketCreator::BuildPaddedPathChallengePacket(
+ const QuicPacketHeader& header,
+ char* buffer,
+ size_t packet_length,
+ QuicPathFrameBuffer* payload,
+ QuicRandom* randomizer,
+ EncryptionLevel level) {
+ DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
+ QuicFrames frames;
+
+ // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
+ randomizer->RandBytes(payload->data(), payload->size());
+ QuicPathChallengeFrame path_challenge_frame(0, *payload);
+ frames.push_back(QuicFrame(&path_challenge_frame));
+
+ if (debug_delegate_ != nullptr) {
+ debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
+ }
+
+ // Add padding to the rest of the packet in order to assess Path MTU
+ // characteristics.
+ QuicPaddingFrame padding_frame;
+ frames.push_back(QuicFrame(padding_frame));
+
+ return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::BuildPathResponsePacket(
+ const QuicPacketHeader& header,
+ char* buffer,
+ size_t packet_length,
+ const QuicDeque<QuicPathFrameBuffer>& payloads,
+ const bool is_padded,
+ EncryptionLevel level) {
+ if (payloads.empty()) {
+ QUIC_BUG
+ << "Attempt to generate connectivity response with no request payloads";
+ return 0;
+ }
+ DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()));
+
+ std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
+ for (const QuicPathFrameBuffer& payload : payloads) {
+ // Note that the control frame ID can be 0 since this is not retransmitted.
+ path_response_frames.push_back(
+ std::make_unique<QuicPathResponseFrame>(0, payload));
+ }
+
+ QuicFrames frames;
+ for (const std::unique_ptr<QuicPathResponseFrame>& path_response_frame :
+ path_response_frames) {
+ frames.push_back(QuicFrame(path_response_frame.get()));
+ if (debug_delegate_ != nullptr) {
+ debug_delegate_->OnFrameAddedToPacket(
+ QuicFrame(path_response_frame.get()));
+ }
+ }
+
+ if (is_padded) {
+ // Add padding to the rest of the packet in order to assess Path MTU
+ // characteristics.
+ QuicPaddingFrame padding_frame;
+ frames.push_back(QuicFrame(padding_frame));
+ }
+
+ return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
+size_t QuicPacketCreator::BuildConnectivityProbingPacket(
+ const QuicPacketHeader& header,
+ char* buffer,
+ size_t packet_length,
+ EncryptionLevel level) {
+ QuicFrames frames;
+
+ // Write a PING frame, which has no data payload.
+ QuicPingFrame ping_frame;
+ frames.push_back(QuicFrame(ping_frame));
+
+ // Add padding to the rest of the packet.
+ QuicPaddingFrame padding_frame;
+ frames.push_back(QuicFrame(padding_frame));
+
+ return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
+}
+
// TODO(b/74062209): Make this a public method of framer?
SerializedPacket QuicPacketCreator::NoPacket() {
return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,