xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/frames/quic_frame.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright (c) 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "quiche/quic/core/frames/quic_frame.h"
6 
7 #include "quiche/quic/core/frames/quic_new_connection_id_frame.h"
8 #include "quiche/quic/core/frames/quic_reset_stream_at_frame.h"
9 #include "quiche/quic/core/frames/quic_retire_connection_id_frame.h"
10 #include "quiche/quic/core/frames/quic_rst_stream_frame.h"
11 #include "quiche/quic/core/quic_constants.h"
12 #include "quiche/quic/core/quic_types.h"
13 #include "quiche/quic/platform/api/quic_bug_tracker.h"
14 #include "quiche/quic/platform/api/quic_logging.h"
15 #include "quiche/common/platform/api/quiche_mem_slice.h"
16 #include "quiche/common/quiche_buffer_allocator.h"
17 
18 namespace quic {
19 
QuicFrame()20 QuicFrame::QuicFrame() {}
21 
QuicFrame(QuicPaddingFrame padding_frame)22 QuicFrame::QuicFrame(QuicPaddingFrame padding_frame)
23     : padding_frame(padding_frame) {}
24 
QuicFrame(QuicStreamFrame stream_frame)25 QuicFrame::QuicFrame(QuicStreamFrame stream_frame)
26     : stream_frame(stream_frame) {}
27 
QuicFrame(QuicHandshakeDoneFrame handshake_done_frame)28 QuicFrame::QuicFrame(QuicHandshakeDoneFrame handshake_done_frame)
29     : handshake_done_frame(handshake_done_frame) {}
30 
QuicFrame(QuicCryptoFrame * crypto_frame)31 QuicFrame::QuicFrame(QuicCryptoFrame* crypto_frame)
32     : type(CRYPTO_FRAME), crypto_frame(crypto_frame) {}
33 
QuicFrame(QuicAckFrame * frame)34 QuicFrame::QuicFrame(QuicAckFrame* frame) : type(ACK_FRAME), ack_frame(frame) {}
35 
QuicFrame(QuicMtuDiscoveryFrame frame)36 QuicFrame::QuicFrame(QuicMtuDiscoveryFrame frame)
37     : mtu_discovery_frame(frame) {}
38 
QuicFrame(QuicStopWaitingFrame frame)39 QuicFrame::QuicFrame(QuicStopWaitingFrame frame) : stop_waiting_frame(frame) {}
40 
QuicFrame(QuicPingFrame frame)41 QuicFrame::QuicFrame(QuicPingFrame frame) : ping_frame(frame) {}
42 
QuicFrame(QuicRstStreamFrame * frame)43 QuicFrame::QuicFrame(QuicRstStreamFrame* frame)
44     : type(RST_STREAM_FRAME), rst_stream_frame(frame) {}
45 
QuicFrame(QuicConnectionCloseFrame * frame)46 QuicFrame::QuicFrame(QuicConnectionCloseFrame* frame)
47     : type(CONNECTION_CLOSE_FRAME), connection_close_frame(frame) {}
48 
QuicFrame(QuicGoAwayFrame * frame)49 QuicFrame::QuicFrame(QuicGoAwayFrame* frame)
50     : type(GOAWAY_FRAME), goaway_frame(frame) {}
51 
QuicFrame(QuicWindowUpdateFrame frame)52 QuicFrame::QuicFrame(QuicWindowUpdateFrame frame)
53     : window_update_frame(frame) {}
54 
QuicFrame(QuicBlockedFrame frame)55 QuicFrame::QuicFrame(QuicBlockedFrame frame) : blocked_frame(frame) {}
56 
QuicFrame(QuicNewConnectionIdFrame * frame)57 QuicFrame::QuicFrame(QuicNewConnectionIdFrame* frame)
58     : type(NEW_CONNECTION_ID_FRAME), new_connection_id_frame(frame) {}
59 
QuicFrame(QuicRetireConnectionIdFrame * frame)60 QuicFrame::QuicFrame(QuicRetireConnectionIdFrame* frame)
61     : type(RETIRE_CONNECTION_ID_FRAME), retire_connection_id_frame(frame) {}
62 
QuicFrame(QuicMaxStreamsFrame frame)63 QuicFrame::QuicFrame(QuicMaxStreamsFrame frame) : max_streams_frame(frame) {}
64 
QuicFrame(QuicStreamsBlockedFrame frame)65 QuicFrame::QuicFrame(QuicStreamsBlockedFrame frame)
66     : streams_blocked_frame(frame) {}
67 
QuicFrame(QuicPathResponseFrame frame)68 QuicFrame::QuicFrame(QuicPathResponseFrame frame)
69     : path_response_frame(frame) {}
70 
QuicFrame(QuicPathChallengeFrame frame)71 QuicFrame::QuicFrame(QuicPathChallengeFrame frame)
72     : path_challenge_frame(frame) {}
73 
QuicFrame(QuicStopSendingFrame frame)74 QuicFrame::QuicFrame(QuicStopSendingFrame frame) : stop_sending_frame(frame) {}
75 
QuicFrame(QuicMessageFrame * frame)76 QuicFrame::QuicFrame(QuicMessageFrame* frame)
77     : type(MESSAGE_FRAME), message_frame(frame) {}
78 
QuicFrame(QuicNewTokenFrame * frame)79 QuicFrame::QuicFrame(QuicNewTokenFrame* frame)
80     : type(NEW_TOKEN_FRAME), new_token_frame(frame) {}
81 
QuicFrame(QuicAckFrequencyFrame * frame)82 QuicFrame::QuicFrame(QuicAckFrequencyFrame* frame)
83     : type(ACK_FREQUENCY_FRAME), ack_frequency_frame(frame) {}
84 
QuicFrame(QuicResetStreamAtFrame * frame)85 QuicFrame::QuicFrame(QuicResetStreamAtFrame* frame)
86     : type(RESET_STREAM_AT_FRAME), reset_stream_at_frame(frame) {}
87 
DeleteFrames(QuicFrames * frames)88 void DeleteFrames(QuicFrames* frames) {
89   for (QuicFrame& frame : *frames) {
90     DeleteFrame(&frame);
91   }
92   frames->clear();
93 }
94 
DeleteFrame(QuicFrame * frame)95 void DeleteFrame(QuicFrame* frame) {
96 #if QUIC_FRAME_DEBUG
97   // If the frame is not inlined, check that it can be safely deleted.
98   if (frame->type != PADDING_FRAME && frame->type != MTU_DISCOVERY_FRAME &&
99       frame->type != PING_FRAME && frame->type != MAX_STREAMS_FRAME &&
100       frame->type != STOP_WAITING_FRAME &&
101       frame->type != STREAMS_BLOCKED_FRAME && frame->type != STREAM_FRAME &&
102       frame->type != HANDSHAKE_DONE_FRAME &&
103       frame->type != WINDOW_UPDATE_FRAME && frame->type != BLOCKED_FRAME &&
104       frame->type != STOP_SENDING_FRAME &&
105       frame->type != PATH_CHALLENGE_FRAME &&
106       frame->type != PATH_RESPONSE_FRAME) {
107     QUICHE_CHECK(!frame->delete_forbidden) << *frame;
108   }
109 #endif  // QUIC_FRAME_DEBUG
110   switch (frame->type) {
111     // Frames smaller than a pointer are inlined, so don't need to be deleted.
112     case PADDING_FRAME:
113     case MTU_DISCOVERY_FRAME:
114     case PING_FRAME:
115     case MAX_STREAMS_FRAME:
116     case STOP_WAITING_FRAME:
117     case STREAMS_BLOCKED_FRAME:
118     case STREAM_FRAME:
119     case HANDSHAKE_DONE_FRAME:
120     case WINDOW_UPDATE_FRAME:
121     case BLOCKED_FRAME:
122     case STOP_SENDING_FRAME:
123     case PATH_CHALLENGE_FRAME:
124     case PATH_RESPONSE_FRAME:
125       break;
126     case ACK_FRAME:
127       delete frame->ack_frame;
128       break;
129     case RST_STREAM_FRAME:
130       delete frame->rst_stream_frame;
131       break;
132     case CONNECTION_CLOSE_FRAME:
133       delete frame->connection_close_frame;
134       break;
135     case GOAWAY_FRAME:
136       delete frame->goaway_frame;
137       break;
138     case NEW_CONNECTION_ID_FRAME:
139       delete frame->new_connection_id_frame;
140       break;
141     case RETIRE_CONNECTION_ID_FRAME:
142       delete frame->retire_connection_id_frame;
143       break;
144     case MESSAGE_FRAME:
145       delete frame->message_frame;
146       break;
147     case CRYPTO_FRAME:
148       delete frame->crypto_frame;
149       break;
150     case NEW_TOKEN_FRAME:
151       delete frame->new_token_frame;
152       break;
153     case ACK_FREQUENCY_FRAME:
154       delete frame->ack_frequency_frame;
155       break;
156     case RESET_STREAM_AT_FRAME:
157       delete frame->reset_stream_at_frame;
158       break;
159     case NUM_FRAME_TYPES:
160       QUICHE_DCHECK(false) << "Cannot delete type: " << frame->type;
161   }
162 }
163 
RemoveFramesForStream(QuicFrames * frames,QuicStreamId stream_id)164 void RemoveFramesForStream(QuicFrames* frames, QuicStreamId stream_id) {
165   auto it = frames->begin();
166   while (it != frames->end()) {
167     if (it->type != STREAM_FRAME || it->stream_frame.stream_id != stream_id) {
168       ++it;
169       continue;
170     }
171     it = frames->erase(it);
172   }
173 }
174 
IsControlFrame(QuicFrameType type)175 bool IsControlFrame(QuicFrameType type) {
176   switch (type) {
177     case RST_STREAM_FRAME:
178     case GOAWAY_FRAME:
179     case WINDOW_UPDATE_FRAME:
180     case BLOCKED_FRAME:
181     case STREAMS_BLOCKED_FRAME:
182     case MAX_STREAMS_FRAME:
183     case PING_FRAME:
184     case STOP_SENDING_FRAME:
185     case NEW_CONNECTION_ID_FRAME:
186     case RETIRE_CONNECTION_ID_FRAME:
187     case HANDSHAKE_DONE_FRAME:
188     case ACK_FREQUENCY_FRAME:
189     case NEW_TOKEN_FRAME:
190     case RESET_STREAM_AT_FRAME:
191       return true;
192     default:
193       return false;
194   }
195 }
196 
GetControlFrameId(const QuicFrame & frame)197 QuicControlFrameId GetControlFrameId(const QuicFrame& frame) {
198   switch (frame.type) {
199     case RST_STREAM_FRAME:
200       return frame.rst_stream_frame->control_frame_id;
201     case GOAWAY_FRAME:
202       return frame.goaway_frame->control_frame_id;
203     case WINDOW_UPDATE_FRAME:
204       return frame.window_update_frame.control_frame_id;
205     case BLOCKED_FRAME:
206       return frame.blocked_frame.control_frame_id;
207     case STREAMS_BLOCKED_FRAME:
208       return frame.streams_blocked_frame.control_frame_id;
209     case MAX_STREAMS_FRAME:
210       return frame.max_streams_frame.control_frame_id;
211     case PING_FRAME:
212       return frame.ping_frame.control_frame_id;
213     case STOP_SENDING_FRAME:
214       return frame.stop_sending_frame.control_frame_id;
215     case NEW_CONNECTION_ID_FRAME:
216       return frame.new_connection_id_frame->control_frame_id;
217     case RETIRE_CONNECTION_ID_FRAME:
218       return frame.retire_connection_id_frame->control_frame_id;
219     case HANDSHAKE_DONE_FRAME:
220       return frame.handshake_done_frame.control_frame_id;
221     case ACK_FREQUENCY_FRAME:
222       return frame.ack_frequency_frame->control_frame_id;
223     case NEW_TOKEN_FRAME:
224       return frame.new_token_frame->control_frame_id;
225     case RESET_STREAM_AT_FRAME:
226       return frame.reset_stream_at_frame->control_frame_id;
227     default:
228       return kInvalidControlFrameId;
229   }
230 }
231 
SetControlFrameId(QuicControlFrameId control_frame_id,QuicFrame * frame)232 void SetControlFrameId(QuicControlFrameId control_frame_id, QuicFrame* frame) {
233   switch (frame->type) {
234     case RST_STREAM_FRAME:
235       frame->rst_stream_frame->control_frame_id = control_frame_id;
236       return;
237     case GOAWAY_FRAME:
238       frame->goaway_frame->control_frame_id = control_frame_id;
239       return;
240     case WINDOW_UPDATE_FRAME:
241       frame->window_update_frame.control_frame_id = control_frame_id;
242       return;
243     case BLOCKED_FRAME:
244       frame->blocked_frame.control_frame_id = control_frame_id;
245       return;
246     case PING_FRAME:
247       frame->ping_frame.control_frame_id = control_frame_id;
248       return;
249     case STREAMS_BLOCKED_FRAME:
250       frame->streams_blocked_frame.control_frame_id = control_frame_id;
251       return;
252     case MAX_STREAMS_FRAME:
253       frame->max_streams_frame.control_frame_id = control_frame_id;
254       return;
255     case STOP_SENDING_FRAME:
256       frame->stop_sending_frame.control_frame_id = control_frame_id;
257       return;
258     case NEW_CONNECTION_ID_FRAME:
259       frame->new_connection_id_frame->control_frame_id = control_frame_id;
260       return;
261     case RETIRE_CONNECTION_ID_FRAME:
262       frame->retire_connection_id_frame->control_frame_id = control_frame_id;
263       return;
264     case HANDSHAKE_DONE_FRAME:
265       frame->handshake_done_frame.control_frame_id = control_frame_id;
266       return;
267     case ACK_FREQUENCY_FRAME:
268       frame->ack_frequency_frame->control_frame_id = control_frame_id;
269       return;
270     case NEW_TOKEN_FRAME:
271       frame->new_token_frame->control_frame_id = control_frame_id;
272       return;
273     case RESET_STREAM_AT_FRAME:
274       frame->reset_stream_at_frame->control_frame_id = control_frame_id;
275       return;
276     default:
277       QUIC_BUG(quic_bug_12594_1)
278           << "Try to set control frame id of a frame without control frame id";
279   }
280 }
281 
CopyRetransmittableControlFrame(const QuicFrame & frame)282 QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame) {
283   QuicFrame copy;
284   switch (frame.type) {
285     case RST_STREAM_FRAME:
286       copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
287       break;
288     case GOAWAY_FRAME:
289       copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
290       break;
291     case WINDOW_UPDATE_FRAME:
292       copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
293       break;
294     case BLOCKED_FRAME:
295       copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
296       break;
297     case PING_FRAME:
298       copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
299       break;
300     case STOP_SENDING_FRAME:
301       copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
302       break;
303     case NEW_CONNECTION_ID_FRAME:
304       copy = QuicFrame(
305           new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
306       break;
307     case RETIRE_CONNECTION_ID_FRAME:
308       copy = QuicFrame(
309           new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
310       break;
311     case STREAMS_BLOCKED_FRAME:
312       copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
313       break;
314     case MAX_STREAMS_FRAME:
315       copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
316       break;
317     case HANDSHAKE_DONE_FRAME:
318       copy = QuicFrame(
319           QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
320       break;
321     case ACK_FREQUENCY_FRAME:
322       copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
323       break;
324     case NEW_TOKEN_FRAME:
325       copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
326       break;
327     case RESET_STREAM_AT_FRAME:
328       copy =
329           QuicFrame(new QuicResetStreamAtFrame(*frame.reset_stream_at_frame));
330       break;
331     default:
332       QUIC_BUG(quic_bug_10533_1)
333           << "Try to copy a non-retransmittable control frame: " << frame;
334       copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
335       break;
336   }
337   return copy;
338 }
339 
CopyQuicFrame(quiche::QuicheBufferAllocator * allocator,const QuicFrame & frame)340 QuicFrame CopyQuicFrame(quiche::QuicheBufferAllocator* allocator,
341                         const QuicFrame& frame) {
342   QuicFrame copy;
343   switch (frame.type) {
344     case PADDING_FRAME:
345       copy = QuicFrame(QuicPaddingFrame(frame.padding_frame));
346       break;
347     case RST_STREAM_FRAME:
348       copy = QuicFrame(new QuicRstStreamFrame(*frame.rst_stream_frame));
349       break;
350     case CONNECTION_CLOSE_FRAME:
351       copy = QuicFrame(
352           new QuicConnectionCloseFrame(*frame.connection_close_frame));
353       break;
354     case GOAWAY_FRAME:
355       copy = QuicFrame(new QuicGoAwayFrame(*frame.goaway_frame));
356       break;
357     case WINDOW_UPDATE_FRAME:
358       copy = QuicFrame(QuicWindowUpdateFrame(frame.window_update_frame));
359       break;
360     case BLOCKED_FRAME:
361       copy = QuicFrame(QuicBlockedFrame(frame.blocked_frame));
362       break;
363     case STOP_WAITING_FRAME:
364       copy = QuicFrame(QuicStopWaitingFrame(frame.stop_waiting_frame));
365       break;
366     case PING_FRAME:
367       copy = QuicFrame(QuicPingFrame(frame.ping_frame.control_frame_id));
368       break;
369     case CRYPTO_FRAME:
370       copy = QuicFrame(new QuicCryptoFrame(*frame.crypto_frame));
371       break;
372     case STREAM_FRAME:
373       copy = QuicFrame(QuicStreamFrame(frame.stream_frame));
374       break;
375     case ACK_FRAME:
376       copy = QuicFrame(new QuicAckFrame(*frame.ack_frame));
377       break;
378     case MTU_DISCOVERY_FRAME:
379       copy = QuicFrame(QuicMtuDiscoveryFrame(frame.mtu_discovery_frame));
380       break;
381     case NEW_CONNECTION_ID_FRAME:
382       copy = QuicFrame(
383           new QuicNewConnectionIdFrame(*frame.new_connection_id_frame));
384       break;
385     case MAX_STREAMS_FRAME:
386       copy = QuicFrame(QuicMaxStreamsFrame(frame.max_streams_frame));
387       break;
388     case STREAMS_BLOCKED_FRAME:
389       copy = QuicFrame(QuicStreamsBlockedFrame(frame.streams_blocked_frame));
390       break;
391     case PATH_RESPONSE_FRAME:
392       copy = QuicFrame(QuicPathResponseFrame(frame.path_response_frame));
393       break;
394     case PATH_CHALLENGE_FRAME:
395       copy = QuicFrame(QuicPathChallengeFrame(frame.path_challenge_frame));
396       break;
397     case STOP_SENDING_FRAME:
398       copy = QuicFrame(QuicStopSendingFrame(frame.stop_sending_frame));
399       break;
400     case MESSAGE_FRAME:
401       copy = QuicFrame(new QuicMessageFrame(frame.message_frame->message_id));
402       copy.message_frame->data = frame.message_frame->data;
403       copy.message_frame->message_length = frame.message_frame->message_length;
404       for (const auto& slice : frame.message_frame->message_data) {
405         quiche::QuicheBuffer buffer =
406             quiche::QuicheBuffer::Copy(allocator, slice.AsStringView());
407         copy.message_frame->message_data.push_back(
408             quiche::QuicheMemSlice(std::move(buffer)));
409       }
410       break;
411     case NEW_TOKEN_FRAME:
412       copy = QuicFrame(new QuicNewTokenFrame(*frame.new_token_frame));
413       break;
414     case RETIRE_CONNECTION_ID_FRAME:
415       copy = QuicFrame(
416           new QuicRetireConnectionIdFrame(*frame.retire_connection_id_frame));
417       break;
418     case HANDSHAKE_DONE_FRAME:
419       copy = QuicFrame(
420           QuicHandshakeDoneFrame(frame.handshake_done_frame.control_frame_id));
421       break;
422     case ACK_FREQUENCY_FRAME:
423       copy = QuicFrame(new QuicAckFrequencyFrame(*frame.ack_frequency_frame));
424       break;
425     case RESET_STREAM_AT_FRAME:
426       copy =
427           QuicFrame(new QuicResetStreamAtFrame(*frame.reset_stream_at_frame));
428       break;
429     default:
430       QUIC_BUG(quic_bug_10533_2) << "Cannot copy frame: " << frame;
431       copy = QuicFrame(QuicPingFrame(kInvalidControlFrameId));
432       break;
433   }
434   return copy;
435 }
436 
CopyQuicFrames(quiche::QuicheBufferAllocator * allocator,const QuicFrames & frames)437 QuicFrames CopyQuicFrames(quiche::QuicheBufferAllocator* allocator,
438                           const QuicFrames& frames) {
439   QuicFrames copy;
440   for (const auto& frame : frames) {
441     copy.push_back(CopyQuicFrame(allocator, frame));
442   }
443   return copy;
444 }
445 
operator <<(std::ostream & os,const QuicFrame & frame)446 std::ostream& operator<<(std::ostream& os, const QuicFrame& frame) {
447   switch (frame.type) {
448     case PADDING_FRAME: {
449       os << "type { PADDING_FRAME } " << frame.padding_frame;
450       break;
451     }
452     case RST_STREAM_FRAME: {
453       os << "type { RST_STREAM_FRAME } " << *(frame.rst_stream_frame);
454       break;
455     }
456     case CONNECTION_CLOSE_FRAME: {
457       os << "type { CONNECTION_CLOSE_FRAME } "
458          << *(frame.connection_close_frame);
459       break;
460     }
461     case GOAWAY_FRAME: {
462       os << "type { GOAWAY_FRAME } " << *(frame.goaway_frame);
463       break;
464     }
465     case WINDOW_UPDATE_FRAME: {
466       os << "type { WINDOW_UPDATE_FRAME } " << frame.window_update_frame;
467       break;
468     }
469     case BLOCKED_FRAME: {
470       os << "type { BLOCKED_FRAME } " << frame.blocked_frame;
471       break;
472     }
473     case STREAM_FRAME: {
474       os << "type { STREAM_FRAME } " << frame.stream_frame;
475       break;
476     }
477     case ACK_FRAME: {
478       os << "type { ACK_FRAME } " << *(frame.ack_frame);
479       break;
480     }
481     case STOP_WAITING_FRAME: {
482       os << "type { STOP_WAITING_FRAME } " << frame.stop_waiting_frame;
483       break;
484     }
485     case PING_FRAME: {
486       os << "type { PING_FRAME } " << frame.ping_frame;
487       break;
488     }
489     case CRYPTO_FRAME: {
490       os << "type { CRYPTO_FRAME } " << *(frame.crypto_frame);
491       break;
492     }
493     case MTU_DISCOVERY_FRAME: {
494       os << "type { MTU_DISCOVERY_FRAME } ";
495       break;
496     }
497     case NEW_CONNECTION_ID_FRAME:
498       os << "type { NEW_CONNECTION_ID } " << *(frame.new_connection_id_frame);
499       break;
500     case RETIRE_CONNECTION_ID_FRAME:
501       os << "type { RETIRE_CONNECTION_ID } "
502          << *(frame.retire_connection_id_frame);
503       break;
504     case MAX_STREAMS_FRAME:
505       os << "type { MAX_STREAMS } " << frame.max_streams_frame;
506       break;
507     case STREAMS_BLOCKED_FRAME:
508       os << "type { STREAMS_BLOCKED } " << frame.streams_blocked_frame;
509       break;
510     case PATH_RESPONSE_FRAME:
511       os << "type { PATH_RESPONSE } " << frame.path_response_frame;
512       break;
513     case PATH_CHALLENGE_FRAME:
514       os << "type { PATH_CHALLENGE } " << frame.path_challenge_frame;
515       break;
516     case STOP_SENDING_FRAME:
517       os << "type { STOP_SENDING } " << frame.stop_sending_frame;
518       break;
519     case MESSAGE_FRAME:
520       os << "type { MESSAGE_FRAME }" << *(frame.message_frame);
521       break;
522     case NEW_TOKEN_FRAME:
523       os << "type { NEW_TOKEN_FRAME }" << *(frame.new_token_frame);
524       break;
525     case HANDSHAKE_DONE_FRAME:
526       os << "type { HANDSHAKE_DONE_FRAME } " << frame.handshake_done_frame;
527       break;
528     case ACK_FREQUENCY_FRAME:
529       os << "type { ACK_FREQUENCY_FRAME } " << *(frame.ack_frequency_frame);
530       break;
531     case RESET_STREAM_AT_FRAME:
532       os << "type { RESET_STREAM_AT_FRAME } " << *(frame.reset_stream_at_frame);
533       break;
534     default: {
535       QUIC_LOG(ERROR) << "Unknown frame type: " << frame.type;
536       break;
537     }
538   }
539   return os;
540 }
541 
QuicFrameToString(const QuicFrame & frame)542 QUICHE_EXPORT std::string QuicFrameToString(const QuicFrame& frame) {
543   std::ostringstream os;
544   os << frame;
545   return os.str();
546 }
547 
QuicFramesToString(const QuicFrames & frames)548 std::string QuicFramesToString(const QuicFrames& frames) {
549   std::ostringstream os;
550   for (const QuicFrame& frame : frames) {
551     os << frame;
552   }
553   return os.str();
554 }
555 
556 }  // namespace quic
557