gfe-relnote: Add QuicPacketCreator::SerializeCoalescedPacket function. Not used yet. Not protected.
PiperOrigin-RevId: 276529504
Change-Id: Id9ddd1c7af0b52e12e75c754295e10d23058ee62
diff --git a/quic/core/quic_packet_creator.cc b/quic/core/quic_packet_creator.cc
index 0dc2921..fa45cf9 100644
--- a/quic/core/quic_packet_creator.cc
+++ b/quic/core/quic_packet_creator.cc
@@ -53,6 +53,38 @@
}
}
+// ScopedPacketContextSwitcher saves |packet|'s states and change states
+// during its construction. When the switcher goes out of scope, it restores
+// saved states.
+class ScopedPacketContextSwitcher {
+ public:
+ ScopedPacketContextSwitcher(QuicPacketNumber packet_number,
+ QuicPacketNumberLength packet_number_length,
+ EncryptionLevel encryption_level,
+ SerializedPacket* packet)
+
+ : saved_packet_number_(packet->packet_number),
+ saved_packet_number_length_(packet->packet_number_length),
+ saved_encryption_level_(packet->encryption_level),
+ packet_(packet) {
+ packet_->packet_number = packet_number,
+ packet_->packet_number_length = packet_number_length;
+ packet_->encryption_level = encryption_level;
+ }
+
+ ~ScopedPacketContextSwitcher() {
+ packet_->packet_number = saved_packet_number_;
+ packet_->packet_number_length = saved_packet_number_length_;
+ packet_->encryption_level = saved_encryption_level_;
+ }
+
+ private:
+ const QuicPacketNumber saved_packet_number_;
+ const QuicPacketNumberLength saved_packet_number_length_;
+ const EncryptionLevel saved_encryption_level_;
+ SerializedPacket* packet_;
+};
+
} // namespace
#define ENDPOINT \
@@ -408,6 +440,53 @@
needs_full_padding_ = false;
}
+size_t QuicPacketCreator::ReserializeInitialPacketInCoalescedPacket(
+ const SerializedPacket& packet,
+ size_t padding_size,
+ char* buffer,
+ size_t buffer_len) {
+ QUIC_BUG_IF(packet.encryption_level != ENCRYPTION_INITIAL);
+ QUIC_BUG_IF(packet.nonretransmittable_frames.empty() &&
+ packet.retransmittable_frames.empty())
+ << "Attempt to serialize empty ENCRYPTION_INITIAL packet in coalesced "
+ "packet";
+ ScopedPacketContextSwitcher switcher(
+ packet.packet_number -
+ 1, // -1 because serialize packet increase packet number.
+ packet.packet_number_length, packet.encryption_level, &packet_);
+ for (const QuicFrame& frame : packet.nonretransmittable_frames) {
+ if (!AddFrame(frame, packet.transmission_type)) {
+ QUIC_BUG << "Failed to serialize frame: " << frame;
+ return 0;
+ }
+ }
+ for (const QuicFrame& frame : packet.retransmittable_frames) {
+ if (!AddFrame(frame, packet.transmission_type)) {
+ QUIC_BUG << "Failed to serialize frame: " << frame;
+ return 0;
+ }
+ }
+ // Add necessary padding.
+ if (padding_size > 0) {
+ QUIC_DVLOG(2) << ENDPOINT << "Add padding of size: " << padding_size;
+ if (!AddFrame(QuicFrame(QuicPaddingFrame(padding_size)),
+ packet.transmission_type)) {
+ QUIC_BUG << "Failed to add padding of size " << padding_size
+ << " when serializing ENCRYPTION_INITIAL "
+ "packet in coalesced packet";
+ return 0;
+ }
+ }
+ SerializePacket(buffer, buffer_len);
+ const size_t encrypted_length = packet_.encrypted_length;
+ // Clear frames in packet_. No need to DeleteFrames since frames are owned by
+ // initial_packet.
+ packet_.retransmittable_frames.clear();
+ packet_.nonretransmittable_frames.clear();
+ ClearPacket();
+ return encrypted_length;
+}
+
void QuicPacketCreator::CreateAndSerializeStreamFrame(
QuicStreamId id,
size_t write_length,
@@ -836,6 +915,43 @@
return framer_->BuildDataPacket(header, frames, buffer, packet_length, level);
}
+size_t QuicPacketCreator::SerializeCoalescedPacket(
+ const QuicCoalescedPacket& coalesced,
+ char* buffer,
+ size_t buffer_len) {
+ QUIC_BUG_IF(packet_.num_padding_bytes != 0);
+ if (HasPendingFrames()) {
+ QUIC_BUG << "Try to serialize coalesced packet with pending frames";
+ return 0;
+ }
+ QUIC_BUG_IF(coalesced.length() == 0)
+ << "Attempt to serialize empty coalesced packet";
+ size_t packet_length = 0;
+ if (coalesced.initial_packet() != nullptr) {
+ size_t initial_length = ReserializeInitialPacketInCoalescedPacket(
+ *coalesced.initial_packet(),
+ /*padding_size=*/coalesced.max_packet_length() - coalesced.length(),
+ buffer, buffer_len);
+ if (initial_length == 0) {
+ QUIC_BUG << "Failed to reserialize ENCRYPTION_INITIAL packet in "
+ "coalesced packet";
+ return 0;
+ }
+ buffer += initial_length;
+ buffer_len -= initial_length;
+ packet_length += initial_length;
+ }
+ size_t length_copied = 0;
+ if (!coalesced.CopyEncryptedBuffers(buffer, buffer_len, &length_copied)) {
+ return 0;
+ }
+ packet_length += length_copied;
+ QUIC_DVLOG(1) << ENDPOINT
+ << "Successfully serialized coalesced packet of length: "
+ << packet_length;
+ return packet_length;
+}
+
// TODO(b/74062209): Make this a public method of framer?
SerializedPacket QuicPacketCreator::NoPacket() {
return SerializedPacket(QuicPacketNumber(), PACKET_1BYTE_PACKET_NUMBER,