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