Change QuicPathChallengeFrame and QuicPathResponseFrame to be inlined quic frame.

PiperOrigin-RevId: 440370636
diff --git a/quiche/quic/core/frames/quic_frame.cc b/quiche/quic/core/frames/quic_frame.cc
index 6200eb2..89c7234 100644
--- a/quiche/quic/core/frames/quic_frame.cc
+++ b/quiche/quic/core/frames/quic_frame.cc
@@ -63,11 +63,11 @@
 QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
     : streams_blocked_frame(frame) {}
 
-QuicFrame::QuicFrame(QuicPathResponseFrame* frame)
-    : type(PATH_RESPONSE_FRAME), path_response_frame(frame) {}
+QuicFrame::QuicFrame(QuicPathResponseFrame frame)
+    : path_response_frame(frame) {}
 
-QuicFrame::QuicFrame(QuicPathChallengeFrame* frame)
-    : type(PATH_CHALLENGE_FRAME), path_challenge_frame(frame) {}
+QuicFrame::QuicFrame(QuicPathChallengeFrame frame)
+    : path_challenge_frame(frame) {}
 
 QuicFrame::QuicFrame(QuicStopSendingFrame frame) : stop_sending_frame(frame) {}
 
@@ -96,7 +96,9 @@
       frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
       frame->type != HANDSHAKE_DONE_FRAME &&
       frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME &&
-      frame->type != STOP_SENDING_FRAME) {
+      frame->type != STOP_SENDING_FRAME &&
+      frame->type != PATH_CHALLENGE_FRAME &&
+      frame->type != PATH_RESPONSE_FRAME) {
     QUICHE_CHECK(!frame->delete_forbidden) << *frame;
   }
 #endif  // QUIC_FRAME_DEBUG
@@ -113,6 +115,8 @@
     case WINDOW_UPDATE_FRAME:
     case BLOCKED_FRAME:
     case STOP_SENDING_FRAME:
+    case PATH_CHALLENGE_FRAME:
+    case PATH_RESPONSE_FRAME:
       break;
     case ACK_FRAME:
       delete frame->ack_frame;
@@ -126,18 +130,12 @@
     case GOAWAY_FRAME:
       delete frame->goaway_frame;
       break;
-    case PATH_CHALLENGE_FRAME:
-      delete frame->path_challenge_frame;
-      break;
     case NEW_CONNECTION_ID_FRAME:
       delete frame->new_connection_id_frame;
       break;
     case RETIRE_CONNECTION_ID_FRAME:
       delete frame->retire_connection_id_frame;
       break;
-    case PATH_RESPONSE_FRAME:
-      delete frame->path_response_frame;
-      break;
     case MESSAGE_FRAME:
       delete frame->message_frame;
       break;
@@ -373,10 +371,10 @@
       copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
       break;
     case PATH_RESPONSE_FRAME:
-      copy = QuicFrame(new QuicPathResponseFrame(*frame.path_response_frame));
+      copy = QuicFrame(QuicPathResponseFrame(frame.path_response_frame));
       break;
     case PATH_CHALLENGE_FRAME:
-      copy = QuicFrame(new QuicPathChallengeFrame(*frame.path_challenge_frame));
+      copy = QuicFrame(QuicPathChallengeFrame(frame.path_challenge_frame));
       break;
     case STOP_SENDING_FRAME:
       copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
@@ -488,10 +486,10 @@
       os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
       break;
     case PATH_RESPONSE_FRAME:
-      os << "type { PATH_RESPONSE } " << *(frame.path_response_frame);
+      os << "type { PATH_RESPONSE } " << frame.path_response_frame;
       break;
     case PATH_CHALLENGE_FRAME:
-      os << "type { PATH_CHALLENGE } " << *(frame.path_challenge_frame);
+      os << "type { PATH_CHALLENGE } " << frame.path_challenge_frame;
       break;
     case STOP_SENDING_FRAME:
       os << "type { STOP_SENDING } " << frame.stop_sending_frame;
diff --git a/quiche/quic/core/frames/quic_frame.h b/quiche/quic/core/frames/quic_frame.h
index ce82ea7..8b0fbfc 100644
--- a/quiche/quic/core/frames/quic_frame.h
+++ b/quiche/quic/core/frames/quic_frame.h
@@ -61,6 +61,8 @@
   explicit QuicFrame(QuicWindowUpdateFrame frame);
   explicit QuicFrame(QuicBlockedFrame frame);
   explicit QuicFrame(QuicStopSendingFrame frame);
+  explicit QuicFrame(QuicPathChallengeFrame frame);
+  explicit QuicFrame(QuicPathResponseFrame frame);
 
   explicit QuicFrame(QuicAckFrame* frame);
   explicit QuicFrame(QuicRstStreamFrame* frame);
@@ -69,8 +71,6 @@
   explicit QuicFrame(QuicNewConnectionIdFrame* frame);
   explicit QuicFrame(QuicRetireConnectionIdFrame* frame);
   explicit QuicFrame(QuicNewTokenFrame* frame);
-  explicit QuicFrame(QuicPathResponseFrame* frame);
-  explicit QuicFrame(QuicPathChallengeFrame* frame);
   explicit QuicFrame(QuicMessageFrame* message_frame);
   explicit QuicFrame(QuicCryptoFrame* crypto_frame);
   explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame);
@@ -94,6 +94,8 @@
     QuicWindowUpdateFrame window_update_frame;
     QuicBlockedFrame blocked_frame;
     QuicStopSendingFrame stop_sending_frame;
+    QuicPathChallengeFrame path_challenge_frame;
+    QuicPathResponseFrame path_response_frame;
 
     // Out of line frames.
     struct {
@@ -103,9 +105,6 @@
       bool delete_forbidden = false;
 #endif  // QUIC_FRAME_DEBUG
 
-      // TODO(wub): These frames can also be inlined without increasing the size
-      // of QuicFrame:
-      // QuicPathResponseFrame, QuicPathChallengeFrame.
       union {
         QuicAckFrame* ack_frame;
         QuicRstStreamFrame* rst_stream_frame;
@@ -113,8 +112,6 @@
         QuicGoAwayFrame* goaway_frame;
         QuicNewConnectionIdFrame* new_connection_id_frame;
         QuicRetireConnectionIdFrame* retire_connection_id_frame;
-        QuicPathResponseFrame* path_response_frame;
-        QuicPathChallengeFrame* path_challenge_frame;
         QuicMessageFrame* message_frame;
         QuicCryptoFrame* crypto_frame;
         QuicAckFrequencyFrame* ack_frequency_frame;
diff --git a/quiche/quic/core/frames/quic_frames_test.cc b/quiche/quic/core/frames/quic_frames_test.cc
index 19c50f5..5626914 100644
--- a/quiche/quic/core/frames/quic_frames_test.cc
+++ b/quiche/quic/core/frames/quic_frames_test.cc
@@ -592,10 +592,10 @@
         frames.push_back(QuicFrame(QuicStreamsBlockedFrame()));
         break;
       case PATH_RESPONSE_FRAME:
-        frames.push_back(QuicFrame(new QuicPathResponseFrame()));
+        frames.push_back(QuicFrame(QuicPathResponseFrame()));
         break;
       case PATH_CHALLENGE_FRAME:
-        frames.push_back(QuicFrame(new QuicPathChallengeFrame()));
+        frames.push_back(QuicFrame(QuicPathChallengeFrame()));
         break;
       case STOP_SENDING_FRAME:
         frames.push_back(QuicFrame(QuicStopSendingFrame()));
@@ -627,16 +627,29 @@
   ASSERT_EQ(NUM_FRAME_TYPES, copy.size());
   for (uint8_t i = 0; i < NUM_FRAME_TYPES; ++i) {
     EXPECT_EQ(i, copy[i].type);
-    if (i != MESSAGE_FRAME) {
-      continue;
+    if (i == MESSAGE_FRAME) {
+      // Verify message frame is correctly copied.
+      EXPECT_EQ(1u, copy[i].message_frame->message_id);
+      EXPECT_EQ(nullptr, copy[i].message_frame->data);
+      EXPECT_EQ(7u, copy[i].message_frame->message_length);
+      ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
+      EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
+                          frames[i].message_frame->message_data[0].data(), 7));
+    } else if (i == PATH_CHALLENGE_FRAME) {
+      EXPECT_EQ(copy[i].path_challenge_frame.control_frame_id,
+                frames[i].path_challenge_frame.control_frame_id);
+      EXPECT_EQ(memcmp(&copy[i].path_challenge_frame.data_buffer,
+                       &frames[i].path_challenge_frame.data_buffer,
+                       copy[i].path_challenge_frame.data_buffer.size()),
+                0);
+    } else if (i == PATH_RESPONSE_FRAME) {
+      EXPECT_EQ(copy[i].path_response_frame.control_frame_id,
+                frames[i].path_response_frame.control_frame_id);
+      EXPECT_EQ(memcmp(&copy[i].path_response_frame.data_buffer,
+                       &frames[i].path_response_frame.data_buffer,
+                       copy[i].path_response_frame.data_buffer.size()),
+                0);
     }
-    // Verify message frame is correctly copied.
-    EXPECT_EQ(1u, copy[i].message_frame->message_id);
-    EXPECT_EQ(nullptr, copy[i].message_frame->data);
-    EXPECT_EQ(7u, copy[i].message_frame->message_length);
-    ASSERT_EQ(1u, copy[i].message_frame->message_data.size());
-    EXPECT_EQ(0, memcmp(copy[i].message_frame->message_data[0].data(),
-                        frames[i].message_frame->message_data[0].data(), 7));
   }
   DeleteFrames(&frames);
   DeleteFrames(&copy);
diff --git a/quiche/quic/core/frames/quic_path_challenge_frame.cc b/quiche/quic/core/frames/quic_path_challenge_frame.cc
index c4781a0..5f4f57b 100644
--- a/quiche/quic/core/frames/quic_path_challenge_frame.cc
+++ b/quiche/quic/core/frames/quic_path_challenge_frame.cc
@@ -9,15 +9,16 @@
 
 namespace quic {
 
+QuicPathChallengeFrame::QuicPathChallengeFrame()
+    : QuicInlinedFrame(PATH_CHALLENGE_FRAME) {}
+
 QuicPathChallengeFrame::QuicPathChallengeFrame(
-    QuicControlFrameId control_frame_id,
-    const QuicPathFrameBuffer& data_buff)
-    : control_frame_id(control_frame_id) {
+    QuicControlFrameId control_frame_id, const QuicPathFrameBuffer& data_buff)
+    : QuicInlinedFrame(PATH_CHALLENGE_FRAME),
+      control_frame_id(control_frame_id) {
   memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
 }
 
-QuicPathChallengeFrame::~QuicPathChallengeFrame() {}
-
 std::ostream& operator<<(std::ostream& os,
                          const QuicPathChallengeFrame& frame) {
   os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
diff --git a/quiche/quic/core/frames/quic_path_challenge_frame.h b/quiche/quic/core/frames/quic_path_challenge_frame.h
index fb0ad24..34dd40b 100644
--- a/quiche/quic/core/frames/quic_path_challenge_frame.h
+++ b/quiche/quic/core/frames/quic_path_challenge_frame.h
@@ -8,20 +8,23 @@
 #include <memory>
 #include <ostream>
 
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
 #include "quiche/quic/core/quic_constants.h"
 #include "quiche/quic/core/quic_types.h"
 
 namespace quic {
 
-struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame {
-  QuicPathChallengeFrame() = default;
+struct QUIC_EXPORT_PRIVATE QuicPathChallengeFrame
+    : public QuicInlinedFrame<QuicPathChallengeFrame> {
+  QuicPathChallengeFrame();
   QuicPathChallengeFrame(QuicControlFrameId control_frame_id,
                          const QuicPathFrameBuffer& data_buff);
-  ~QuicPathChallengeFrame();
+  ~QuicPathChallengeFrame() = default;
 
   friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPathChallengeFrame& frame);
+      std::ostream& os, const QuicPathChallengeFrame& frame);
+
+  QuicFrameType type;
 
   // A unique identifier of this control frame. 0 when this frame is received,
   // and non-zero when sent.
diff --git a/quiche/quic/core/frames/quic_path_response_frame.cc b/quiche/quic/core/frames/quic_path_response_frame.cc
index 384387d..0f7a412 100644
--- a/quiche/quic/core/frames/quic_path_response_frame.cc
+++ b/quiche/quic/core/frames/quic_path_response_frame.cc
@@ -9,15 +9,16 @@
 
 namespace quic {
 
+QuicPathResponseFrame::QuicPathResponseFrame()
+    : QuicInlinedFrame(PATH_RESPONSE_FRAME) {}
+
 QuicPathResponseFrame::QuicPathResponseFrame(
-    QuicControlFrameId control_frame_id,
-    const QuicPathFrameBuffer& data_buff)
-    : control_frame_id(control_frame_id) {
+    QuicControlFrameId control_frame_id, const QuicPathFrameBuffer& data_buff)
+    : QuicInlinedFrame(PATH_RESPONSE_FRAME),
+      control_frame_id(control_frame_id) {
   memcpy(data_buffer.data(), data_buff.data(), data_buffer.size());
 }
 
-QuicPathResponseFrame::~QuicPathResponseFrame() {}
-
 std::ostream& operator<<(std::ostream& os, const QuicPathResponseFrame& frame) {
   os << "{ control_frame_id: " << frame.control_frame_id << ", data: "
      << absl::BytesToHexString(absl::string_view(
diff --git a/quiche/quic/core/frames/quic_path_response_frame.h b/quiche/quic/core/frames/quic_path_response_frame.h
index df2391f..5c6a667 100644
--- a/quiche/quic/core/frames/quic_path_response_frame.h
+++ b/quiche/quic/core/frames/quic_path_response_frame.h
@@ -8,20 +8,23 @@
 #include <memory>
 #include <ostream>
 
+#include "quiche/quic/core/frames/quic_inlined_frame.h"
 #include "quiche/quic/core/quic_constants.h"
 #include "quiche/quic/core/quic_types.h"
 
 namespace quic {
 
-struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame {
-  QuicPathResponseFrame() = default;
+struct QUIC_EXPORT_PRIVATE QuicPathResponseFrame
+    : public QuicInlinedFrame<QuicPathResponseFrame> {
+  QuicPathResponseFrame();
   QuicPathResponseFrame(QuicControlFrameId control_frame_id,
                         const QuicPathFrameBuffer& data_buff);
-  ~QuicPathResponseFrame();
+  ~QuicPathResponseFrame() = default;
 
   friend QUIC_EXPORT_PRIVATE std::ostream& operator<<(
-      std::ostream& os,
-      const QuicPathResponseFrame& frame);
+      std::ostream& os, const QuicPathResponseFrame& frame);
+
+  QuicFrameType type;
 
   // A unique identifier of this control frame. 0 when this frame is received,
   // and non-zero when sent.
diff --git a/quiche/quic/core/quic_connection_test.cc b/quiche/quic/core/quic_connection_test.cc
index 1311afe..d7b722c 100644
--- a/quiche/quic/core/quic_connection_test.cc
+++ b/quiche/quic/core/quic_connection_test.cc
@@ -1852,7 +1852,7 @@
 
   // Receiving PATH_RESPONSE should lift the anti-amplification limit.
   QuicFrames frames3;
-  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  frames3.push_back(QuicFrame(QuicPathResponseFrame(99, payload)));
   EXPECT_CALL(visitor_, MaybeSendAddressToken());
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .Times(testing::AtLeast(1u));
@@ -2166,11 +2166,10 @@
           QuicFrame(new QuicNewTokenFrame(1, "new_token")));
       return true;
     }));
-    ProcessFramesPacketWithAddresses({QuicFrame(new QuicPathResponseFrame(
-                                          0, reverse_path_challenge_payload)),
-                                      QuicFrame(&ack_frame)},
-                                     kSelfAddress, kPeerAddress3,
-                                     ENCRYPTION_FORWARD_SECURE);
+    ProcessFramesPacketWithAddresses(
+        {QuicFrame(QuicPathResponseFrame(0, reverse_path_challenge_payload)),
+         QuicFrame(&ack_frame)},
+        kSelfAddress, kPeerAddress3, ENCRYPTION_FORWARD_SECURE);
   }
 }
 
@@ -2540,7 +2539,7 @@
     EXPECT_EQ((connection_.validate_client_address() ? 2 : 3) * bytes_sent,
               QuicConnectionPeer::BytesSentOnAlternativePath(&connection_));
     QuicFrames frames;
-    frames.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+    frames.push_back(QuicFrame(QuicPathResponseFrame(99, payload)));
     ProcessFramesPacketWithAddresses(frames, connection_.self_address(),
                                      kNewPeerAddress,
                                      ENCRYPTION_FORWARD_SECURE);
@@ -11949,7 +11948,7 @@
   EXPECT_EQ(0u, writer_->packets_write_attempts());
 
   QuicFrames frames;
-  frames.push_back(QuicFrame(new QuicPathResponseFrame(
+  frames.push_back(QuicFrame(QuicPathResponseFrame(
       99, new_writer.path_challenge_frames().front().data_buffer)));
   ProcessFramesPacketWithAddresses(frames, kNewSelfAddress, kPeerAddress,
                                    ENCRYPTION_FORWARD_SECURE);
@@ -12174,7 +12173,7 @@
     // address validation.
     QuicFrames frames;
     frames.push_back(
-        QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+        QuicFrame(QuicPathChallengeFrame(0, path_challenge_payload)));
     ProcessFramesPacketWithAddresses(frames, kSelfAddress, kNewPeerAddress,
                                      ENCRYPTION_FORWARD_SECURE);
   } else {
@@ -12352,10 +12351,8 @@
   QuicPathFrameBuffer path_frame_buffer1{0, 1, 2, 3, 4, 5, 6, 7};
   QuicPathFrameBuffer path_frame_buffer2{8, 9, 10, 11, 12, 13, 14, 15};
   QuicFrames frames;
-  frames.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer1)));
-  frames.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer2)));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer1)));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer2)));
   const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
                                           /*port=*/23456);
 
@@ -12395,7 +12392,7 @@
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1_));
   QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer)));
   const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
                                           /*port=*/23456);
 
@@ -12444,7 +12441,7 @@
 
   QuicFrames frames;
   QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer)));
   // PATH_RESPONSE should be flushed out before the rest packet is parsed.
   frames.push_back(QuicFrame(frame1_));
   const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback4(),
@@ -12506,7 +12503,7 @@
   QuicFrames frames;
   frames.push_back(QuicFrame(frame1_));
   QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer)));
   frames.push_back(QuicFrame(frame2_));
   const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
                                           /*port=*/23456);
@@ -12568,7 +12565,7 @@
 
   QuicFrames frames;
   QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
-  frames.push_back(QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer)));
   const QuicSocketAddress kNewPeerAddress(QuicIpAddress::Loopback6(),
                                           /*port=*/23456);
 
@@ -13824,7 +13821,7 @@
   QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
   QuicFrames frames1;
   frames1.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+      QuicFrame(QuicPathChallengeFrame(0, path_challenge_payload)));
   QuicPathFrameBuffer payload;
   EXPECT_CALL(*send_algorithm_,
               OnPacketSent(_, _, _, _, NO_RETRANSMITTABLE_DATA))
@@ -13911,7 +13908,7 @@
 
   // Receiving PATH_RESPONSE should lift the anti-amplification limit.
   QuicFrames frames3;
-  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  frames3.push_back(QuicFrame(QuicPathResponseFrame(99, payload)));
   EXPECT_CALL(visitor_, MaybeSendAddressToken());
   EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
       .Times(testing::AtLeast(1u));
@@ -13979,7 +13976,7 @@
   QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
   QuicFrames frames1;
   frames1.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+      QuicFrame(QuicPathChallengeFrame(0, path_challenge_payload)));
   ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewPeerAddress,
                                    ENCRYPTION_FORWARD_SECURE);
   EXPECT_TRUE(connection_.HasPendingPathValidation());
@@ -13992,7 +13989,7 @@
 
   // Receive PATH_RESPONSE should mark the new peer address validated.
   QuicFrames frames3;
-  frames3.push_back(QuicFrame(new QuicPathResponseFrame(99, payload)));
+  frames3.push_back(QuicFrame(QuicPathResponseFrame(99, payload)));
   ProcessFramesPacketWithAddresses(frames3, kSelfAddress, kNewPeerAddress,
                                    ENCRYPTION_FORWARD_SECURE);
 
@@ -14107,7 +14104,7 @@
   QuicPathFrameBuffer path_challenge_payload{0, 1, 2, 3, 4, 5, 6, 7};
   QuicFrames frames1;
   frames1.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_challenge_payload)));
+      QuicFrame(QuicPathChallengeFrame(0, path_challenge_payload)));
   ProcessFramesPacketWithAddresses(frames1, kSelfAddress, kNewerPeerAddress,
                                    ENCRYPTION_FORWARD_SECURE);
   EXPECT_EQ(kNewPeerAddress, connection_.effective_peer_address());
@@ -15180,7 +15177,7 @@
         frame = QuicFrame(window_update_frame);
         break;
       case PATH_CHALLENGE_FRAME:
-        frame = QuicFrame(&path_challenge_frame);
+        frame = QuicFrame(path_challenge_frame);
         break;
       case STOP_SENDING_FRAME:
         frame = QuicFrame(stop_sending_frame);
@@ -15192,7 +15189,7 @@
         frame = QuicFrame(&retire_connection_id_frame);
         break;
       case PATH_RESPONSE_FRAME:
-        frame = QuicFrame(&path_response_frame);
+        frame = QuicFrame(path_response_frame);
         break;
       case MESSAGE_FRAME:
         frame = QuicFrame(&message_frame);
diff --git a/quiche/quic/core/quic_framer.cc b/quiche/quic/core/quic_framer.cc
index 193ceff..b0f5018 100644
--- a/quiche/quic/core/quic_framer.cc
+++ b/quiche/quic/core/quic_framer.cc
@@ -687,9 +687,9 @@
     case STREAMS_BLOCKED_FRAME:
       return GetStreamsBlockedFrameSize(version, frame.streams_blocked_frame);
     case PATH_RESPONSE_FRAME:
-      return GetPathResponseFrameSize(*frame.path_response_frame);
+      return GetPathResponseFrameSize(frame.path_response_frame);
     case PATH_CHALLENGE_FRAME:
-      return GetPathChallengeFrameSize(*frame.path_challenge_frame);
+      return GetPathChallengeFrameSize(frame.path_challenge_frame);
     case STOP_SENDING_FRAME:
       return GetStopSendingFrameSize(frame.stop_sending_frame);
     case HANDSHAKE_DONE_FRAME:
@@ -1191,14 +1191,14 @@
         }
         break;
       case PATH_CHALLENGE_FRAME:
-        if (!AppendPathChallengeFrame(*frame.path_challenge_frame, writer)) {
+        if (!AppendPathChallengeFrame(frame.path_challenge_frame, writer)) {
           QUIC_BUG(quic_bug_10850_47)
               << "AppendPathChallengeFrame failed: " << detailed_error();
           return 0;
         }
         break;
       case PATH_RESPONSE_FRAME:
-        if (!AppendPathResponseFrame(*frame.path_response_frame, writer)) {
+        if (!AppendPathResponseFrame(frame.path_response_frame, writer)) {
           QUIC_BUG(quic_bug_10850_48)
               << "AppendPathResponseFrame failed: " << detailed_error();
           return 0;
diff --git a/quiche/quic/core/quic_framer_test.cc b/quiche/quic/core/quic_framer_test.cc
index 76bbe4a..7751510 100644
--- a/quiche/quic/core/quic_framer_test.cc
+++ b/quiche/quic/core/quic_framer_test.cc
@@ -12428,7 +12428,7 @@
 
   QuicPathChallengeFrame frame;
   frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
-  QuicFrames frames = {QuicFrame(&frame)};
+  QuicFrames frames = {QuicFrame(frame)};
 
   // clang-format off
   unsigned char packet_ietf[] = {
@@ -12511,7 +12511,7 @@
 
   QuicPathResponseFrame frame;
   frame.data_buffer = QuicPathFrameBuffer({{0, 1, 2, 3, 4, 5, 6, 7}});
-  QuicFrames frames = {QuicFrame(&frame)};
+  QuicFrames frames = {QuicFrame(frame)};
 
   // clang-format off
   unsigned char packet_ietf[] = {
@@ -12600,12 +12600,12 @@
   QuicPathResponseFrame path_response_frame(8, buffer);
   EXPECT_EQ(QuicFramer::GetPathResponseFrameSize(path_response_frame),
             QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&path_response_frame)));
+                framer_.transport_version(), QuicFrame(path_response_frame)));
 
   QuicPathChallengeFrame path_challenge_frame(9, buffer);
   EXPECT_EQ(QuicFramer::GetPathChallengeFrameSize(path_challenge_frame),
             QuicFramer::GetRetransmittableControlFrameSize(
-                framer_.transport_version(), QuicFrame(&path_challenge_frame)));
+                framer_.transport_version(), QuicFrame(path_challenge_frame)));
 
   QuicStopSendingFrame stop_sending_frame(10, 3, QUIC_STREAM_CANCELLED);
   EXPECT_EQ(QuicFramer::GetStopSendingFrameSize(stop_sending_frame),
diff --git a/quiche/quic/core/quic_packet_creator.cc b/quiche/quic/core/quic_packet_creator.cc
index 4390747..988717c 100644
--- a/quiche/quic/core/quic_packet_creator.cc
+++ b/quiche/quic/core/quic_packet_creator.cc
@@ -1056,11 +1056,10 @@
   QuicFrames frames;
 
   // Write a PATH_CHALLENGE frame, which has a random 8-byte payload
-  QuicPathChallengeFrame path_challenge_frame(0, payload);
-  frames.push_back(QuicFrame(&path_challenge_frame));
+  frames.push_back(QuicFrame(QuicPathChallengeFrame(0, payload)));
 
   if (debug_delegate_ != nullptr) {
-    debug_delegate_->OnFrameAddedToPacket(QuicFrame(&path_challenge_frame));
+    debug_delegate_->OnFrameAddedToPacket(frames.back());
   }
 
   // Add padding to the rest of the packet in order to assess Path MTU
@@ -1087,20 +1086,12 @@
   QUICHE_DCHECK(VersionHasIetfQuicFrames(framer_->transport_version()))
       << ENDPOINT;
 
-  std::vector<std::unique_ptr<QuicPathResponseFrame>> path_response_frames;
+  QuicFrames 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()));
+    frames.push_back(QuicFrame(QuicPathResponseFrame(0, payload)));
     if (debug_delegate_ != nullptr) {
-      debug_delegate_->OnFrameAddedToPacket(
-          QuicFrame(path_response_frame.get()));
+      debug_delegate_->OnFrameAddedToPacket(frames.back());
     }
   }
 
@@ -2252,8 +2243,7 @@
       << "Packet flusher is not attached when "
          "generator tries to write stream data.";
   // Write a PATH_CHALLENGE frame, which has a random 8-byte payload.
-  auto path_challenge_frame = new QuicPathChallengeFrame(0, payload);
-  QuicFrame frame(path_challenge_frame);
+  QuicFrame frame(QuicPathChallengeFrame(0, payload));
   if (AddPaddedFrameWithRetry(frame)) {
     return;
   }
@@ -2263,20 +2253,16 @@
   // regression, consider to notify the caller about the sending failure and let
   // the caller to decide if it worth retrying.
   QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_CHALLENGE now";
-  delete path_challenge_frame;
 }
 
 bool QuicPacketCreator::AddPathResponseFrame(
     const QuicPathFrameBuffer& data_buffer) {
-  auto path_response =
-      new QuicPathResponseFrame(kInvalidControlFrameId, data_buffer);
-  QuicFrame frame(path_response);
+  QuicFrame frame(QuicPathResponseFrame(kInvalidControlFrameId, data_buffer));
   if (AddPaddedFrameWithRetry(frame)) {
     return true;
   }
 
   QUIC_DVLOG(1) << ENDPOINT << "Can't send PATH_RESPONSE now";
-  delete path_response;
   return false;
 }
 
diff --git a/quiche/quic/core/quic_sent_packet_manager_test.cc b/quiche/quic/core/quic_sent_packet_manager_test.cc
index fc16612..24485e2 100644
--- a/quiche/quic/core/quic_sent_packet_manager_test.cc
+++ b/quiche/quic/core/quic_sent_packet_manager_test.cc
@@ -4309,7 +4309,7 @@
                           kDefaultLength, false, false);
   QuicPathFrameBuffer path_frame_buffer{0, 1, 2, 3, 4, 5, 6, 7};
   packet.nonretransmittable_frames.push_back(
-      QuicFrame(new QuicPathChallengeFrame(0, path_frame_buffer)));
+      QuicFrame(QuicPathChallengeFrame(0, path_frame_buffer)));
   packet.encryption_level = ENCRYPTION_FORWARD_SECURE;
   manager_.OnPacketSent(&packet, clock_.Now(), NOT_RETRANSMISSION,
                         NO_RETRANSMITTABLE_DATA, false);