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 #ifndef QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_ 6 #define QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_ 7 8 #include <cstddef> 9 #include <ostream> 10 #include <string> 11 #include <type_traits> 12 13 #include "absl/container/inlined_vector.h" 14 #include "quiche/quic/core/frames/quic_ack_frame.h" 15 #include "quiche/quic/core/frames/quic_ack_frequency_frame.h" 16 #include "quiche/quic/core/frames/quic_blocked_frame.h" 17 #include "quiche/quic/core/frames/quic_connection_close_frame.h" 18 #include "quiche/quic/core/frames/quic_crypto_frame.h" 19 #include "quiche/quic/core/frames/quic_goaway_frame.h" 20 #include "quiche/quic/core/frames/quic_handshake_done_frame.h" 21 #include "quiche/quic/core/frames/quic_max_streams_frame.h" 22 #include "quiche/quic/core/frames/quic_message_frame.h" 23 #include "quiche/quic/core/frames/quic_mtu_discovery_frame.h" 24 #include "quiche/quic/core/frames/quic_new_connection_id_frame.h" 25 #include "quiche/quic/core/frames/quic_new_token_frame.h" 26 #include "quiche/quic/core/frames/quic_padding_frame.h" 27 #include "quiche/quic/core/frames/quic_path_challenge_frame.h" 28 #include "quiche/quic/core/frames/quic_path_response_frame.h" 29 #include "quiche/quic/core/frames/quic_ping_frame.h" 30 #include "quiche/quic/core/frames/quic_reset_stream_at_frame.h" 31 #include "quiche/quic/core/frames/quic_retire_connection_id_frame.h" 32 #include "quiche/quic/core/frames/quic_rst_stream_frame.h" 33 #include "quiche/quic/core/frames/quic_stop_sending_frame.h" 34 #include "quiche/quic/core/frames/quic_stop_waiting_frame.h" 35 #include "quiche/quic/core/frames/quic_stream_frame.h" 36 #include "quiche/quic/core/frames/quic_streams_blocked_frame.h" 37 #include "quiche/quic/core/frames/quic_window_update_frame.h" 38 #include "quiche/quic/core/quic_types.h" 39 #include "quiche/common/platform/api/quiche_export.h" 40 #include "quiche/common/quiche_buffer_allocator.h" 41 42 #ifndef QUIC_FRAME_DEBUG 43 #if !defined(NDEBUG) || defined(ADDRESS_SANITIZER) 44 #define QUIC_FRAME_DEBUG 1 45 #else // !defined(NDEBUG) || defined(ADDRESS_SANITIZER) 46 #define QUIC_FRAME_DEBUG 0 47 #endif // !defined(NDEBUG) || defined(ADDRESS_SANITIZER) 48 #endif // QUIC_FRAME_DEBUG 49 50 namespace quic { 51 52 struct QUICHE_EXPORT QuicFrame { 53 QuicFrame(); 54 // Please keep the constructors in the same order as the union below. 55 explicit QuicFrame(QuicPaddingFrame padding_frame); 56 explicit QuicFrame(QuicMtuDiscoveryFrame frame); 57 explicit QuicFrame(QuicPingFrame frame); 58 explicit QuicFrame(QuicMaxStreamsFrame frame); 59 explicit QuicFrame(QuicStopWaitingFrame frame); 60 explicit QuicFrame(QuicStreamsBlockedFrame frame); 61 explicit QuicFrame(QuicStreamFrame stream_frame); 62 explicit QuicFrame(QuicHandshakeDoneFrame handshake_done_frame); 63 explicit QuicFrame(QuicWindowUpdateFrame frame); 64 explicit QuicFrame(QuicBlockedFrame frame); 65 explicit QuicFrame(QuicStopSendingFrame frame); 66 explicit QuicFrame(QuicPathChallengeFrame frame); 67 explicit QuicFrame(QuicPathResponseFrame frame); 68 69 explicit QuicFrame(QuicAckFrame* frame); 70 explicit QuicFrame(QuicRstStreamFrame* frame); 71 explicit QuicFrame(QuicConnectionCloseFrame* frame); 72 explicit QuicFrame(QuicGoAwayFrame* frame); 73 explicit QuicFrame(QuicNewConnectionIdFrame* frame); 74 explicit QuicFrame(QuicRetireConnectionIdFrame* frame); 75 explicit QuicFrame(QuicNewTokenFrame* frame); 76 explicit QuicFrame(QuicMessageFrame* message_frame); 77 explicit QuicFrame(QuicCryptoFrame* crypto_frame); 78 explicit QuicFrame(QuicAckFrequencyFrame* ack_frequency_frame); 79 explicit QuicFrame(QuicResetStreamAtFrame* reset_stream_at_frame); 80 81 QUICHE_EXPORT friend std::ostream& operator<<(std::ostream& os, 82 const QuicFrame& frame); 83 84 union { 85 // Inlined frames. 86 // Overlapping inlined frames have a |type| field at the same 0 offset as 87 // QuicFrame does for out of line frames below, allowing use of the 88 // remaining 7 bytes after offset for frame-type specific fields. 89 QuicPaddingFrame padding_frame; 90 QuicMtuDiscoveryFrame mtu_discovery_frame; 91 QuicPingFrame ping_frame; 92 QuicMaxStreamsFrame max_streams_frame; 93 QuicStopWaitingFrame stop_waiting_frame; 94 QuicStreamsBlockedFrame streams_blocked_frame; 95 QuicStreamFrame stream_frame; 96 QuicHandshakeDoneFrame handshake_done_frame; 97 QuicWindowUpdateFrame window_update_frame; 98 QuicBlockedFrame blocked_frame; 99 QuicStopSendingFrame stop_sending_frame; 100 QuicPathChallengeFrame path_challenge_frame; 101 QuicPathResponseFrame path_response_frame; 102 103 // Out of line frames. 104 struct { 105 QuicFrameType type; 106 107 #if QUIC_FRAME_DEBUG 108 bool delete_forbidden = false; 109 #endif // QUIC_FRAME_DEBUG 110 111 union { 112 QuicAckFrame* ack_frame; 113 QuicRstStreamFrame* rst_stream_frame; 114 QuicConnectionCloseFrame* connection_close_frame; 115 QuicGoAwayFrame* goaway_frame; 116 QuicNewConnectionIdFrame* new_connection_id_frame; 117 QuicRetireConnectionIdFrame* retire_connection_id_frame; 118 QuicMessageFrame* message_frame; 119 QuicCryptoFrame* crypto_frame; 120 QuicAckFrequencyFrame* ack_frequency_frame; 121 QuicNewTokenFrame* new_token_frame; 122 QuicResetStreamAtFrame* reset_stream_at_frame; 123 }; 124 }; 125 }; 126 }; 127 128 static_assert(std::is_standard_layout<QuicFrame>::value, 129 "QuicFrame must have a standard layout"); 130 static_assert(sizeof(QuicFrame) <= 24, 131 "Frames larger than 24 bytes should be referenced by pointer."); 132 static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type), 133 "Offset of |type| must match in QuicFrame and QuicStreamFrame"); 134 135 // A inline size of 1 is chosen to optimize the typical use case of 136 // 1-stream-frame in QuicTransmissionInfo.retransmittable_frames. 137 using QuicFrames = absl::InlinedVector<QuicFrame, 1>; 138 139 // Deletes all the sub-frames contained in |frames|. 140 QUICHE_EXPORT void DeleteFrames(QuicFrames* frames); 141 142 // Delete the sub-frame contained in |frame|. 143 QUICHE_EXPORT void DeleteFrame(QuicFrame* frame); 144 145 // Deletes all the QuicStreamFrames for the specified |stream_id|. 146 QUICHE_EXPORT void RemoveFramesForStream(QuicFrames* frames, 147 QuicStreamId stream_id); 148 149 // Returns true if |type| is a retransmittable control frame. 150 QUICHE_EXPORT bool IsControlFrame(QuicFrameType type); 151 152 // Returns control_frame_id of |frame|. Returns kInvalidControlFrameId if 153 // |frame| does not have a valid control_frame_id. 154 QUICHE_EXPORT QuicControlFrameId GetControlFrameId(const QuicFrame& frame); 155 156 // Sets control_frame_id of |frame| to |control_frame_id|. 157 QUICHE_EXPORT void SetControlFrameId(QuicControlFrameId control_frame_id, 158 QuicFrame* frame); 159 160 // Returns a copy of |frame|. 161 QUICHE_EXPORT QuicFrame CopyRetransmittableControlFrame(const QuicFrame& frame); 162 163 // Returns a copy of |frame|. 164 QUICHE_EXPORT QuicFrame CopyQuicFrame(quiche::QuicheBufferAllocator* allocator, 165 const QuicFrame& frame); 166 167 // Returns a copy of |frames|. 168 QUICHE_EXPORT QuicFrames CopyQuicFrames( 169 quiche::QuicheBufferAllocator* allocator, const QuicFrames& frames); 170 171 // Human-readable description suitable for logging. 172 QUICHE_EXPORT std::string QuicFrameToString(const QuicFrame& frame); 173 QUICHE_EXPORT std::string QuicFramesToString(const QuicFrames& frames); 174 175 } // namespace quic 176 177 #endif // QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_ 178