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 "net/third_party/quiche/src/quic/core/frames/quic_ack_frame.h" 13 #include "net/third_party/quiche/src/quic/core/frames/quic_ack_frequency_frame.h" 14 #include "net/third_party/quiche/src/quic/core/frames/quic_blocked_frame.h" 15 #include "net/third_party/quiche/src/quic/core/frames/quic_connection_close_frame.h" 16 #include "net/third_party/quiche/src/quic/core/frames/quic_crypto_frame.h" 17 #include "net/third_party/quiche/src/quic/core/frames/quic_goaway_frame.h" 18 #include "net/third_party/quiche/src/quic/core/frames/quic_handshake_done_frame.h" 19 #include "net/third_party/quiche/src/quic/core/frames/quic_max_streams_frame.h" 20 #include "net/third_party/quiche/src/quic/core/frames/quic_message_frame.h" 21 #include "net/third_party/quiche/src/quic/core/frames/quic_mtu_discovery_frame.h" 22 #include "net/third_party/quiche/src/quic/core/frames/quic_new_connection_id_frame.h" 23 #include "net/third_party/quiche/src/quic/core/frames/quic_new_token_frame.h" 24 #include "net/third_party/quiche/src/quic/core/frames/quic_padding_frame.h" 25 #include "net/third_party/quiche/src/quic/core/frames/quic_path_challenge_frame.h" 26 #include "net/third_party/quiche/src/quic/core/frames/quic_path_response_frame.h" 27 #include "net/third_party/quiche/src/quic/core/frames/quic_ping_frame.h" 28 #include "net/third_party/quiche/src/quic/core/frames/quic_retire_connection_id_frame.h" 29 #include "net/third_party/quiche/src/quic/core/frames/quic_rst_stream_frame.h" 30 #include "net/third_party/quiche/src/quic/core/frames/quic_stop_sending_frame.h" 31 #include "net/third_party/quiche/src/quic/core/frames/quic_stop_waiting_frame.h" 32 #include "net/third_party/quiche/src/quic/core/frames/quic_stream_frame.h" 33 #include "net/third_party/quiche/src/quic/core/frames/quic_streams_blocked_frame.h" 34 #include "net/third_party/quiche/src/quic/core/frames/quic_window_update_frame.h" 35 #include "net/third_party/quiche/src/quic/core/quic_types.h" 36 #include "net/third_party/quiche/src/quic/platform/api/quic_containers.h" 37 #include "net/third_party/quiche/src/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 61 explicit QuicFrame(QuicAckFrame* frame); 62 explicit QuicFrame(QuicRstStreamFrame* frame); 63 explicit QuicFrame(QuicConnectionCloseFrame* frame); 64 explicit QuicFrame(QuicGoAwayFrame* frame); 65 explicit QuicFrame(QuicWindowUpdateFrame* frame); 66 explicit QuicFrame(QuicBlockedFrame* frame); 67 explicit QuicFrame(QuicNewConnectionIdFrame* frame); 68 explicit QuicFrame(QuicRetireConnectionIdFrame* frame); 69 explicit QuicFrame(QuicNewTokenFrame* frame); 70 explicit QuicFrame(QuicPathResponseFrame* frame); 71 explicit QuicFrame(QuicPathChallengeFrame* frame); 72 explicit QuicFrame(QuicStopSendingFrame* 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 94 // Out of line frames. 95 struct { 96 QuicFrameType type; 97 98 #if QUIC_FRAME_DEBUG 99 bool delete_forbidden = false; 100 #endif // QUIC_FRAME_DEBUG 101 102 // TODO(wub): These frames can also be inlined without increasing the size 103 // of QuicFrame: QuicRstStreamFrame, QuicWindowUpdateFrame, 104 // QuicBlockedFrame, QuicPathResponseFrame, QuicPathChallengeFrame and 105 // QuicStopSendingFrame. 106 union { 107 QuicAckFrame* ack_frame; 108 QuicRstStreamFrame* rst_stream_frame; 109 QuicConnectionCloseFrame* connection_close_frame; 110 QuicGoAwayFrame* goaway_frame; 111 QuicWindowUpdateFrame* window_update_frame; 112 QuicBlockedFrame* blocked_frame; 113 QuicNewConnectionIdFrame* new_connection_id_frame; 114 QuicRetireConnectionIdFrame* retire_connection_id_frame; 115 QuicPathResponseFrame* path_response_frame; 116 QuicPathChallengeFrame* path_challenge_frame; 117 QuicStopSendingFrame* stop_sending_frame; 118 QuicMessageFrame* message_frame; 119 QuicCryptoFrame* crypto_frame; 120 QuicAckFrequencyFrame* ack_frequency_frame; 121 QuicNewTokenFrame* new_token_frame; 122 }; 123 }; 124 }; 125 }; 126 127 static_assert(std::is_standard_layout<QuicFrame>::value, 128 "QuicFrame must have a standard layout"); 129 static_assert(sizeof(QuicFrame) <= 24, 130 "Frames larger than 24 bytes should be referenced by pointer."); 131 static_assert(offsetof(QuicStreamFrame, type) == offsetof(QuicFrame, type), 132 "Offset of |type| must match in QuicFrame and QuicStreamFrame"); 133 134 // A inline size of 1 is chosen to optimize the typical use case of 135 // 1-stream-frame in QuicTransmissionInfo.retransmittable_frames. 136 using QuicFrames = QuicInlinedVector<QuicFrame, 1>; 137 138 // Deletes all the sub-frames contained in |frames|. 139 QUIC_EXPORT_PRIVATE void DeleteFrames(QuicFrames* frames); 140 141 // Delete the sub-frame contained in |frame|. 142 QUIC_EXPORT_PRIVATE void DeleteFrame(QuicFrame* frame); 143 144 // Deletes all the QuicStreamFrames for the specified |stream_id|. 145 QUIC_EXPORT_PRIVATE void RemoveFramesForStream(QuicFrames* frames, 146 QuicStreamId stream_id); 147 148 // Returns true if |type| is a retransmittable control frame. 149 QUIC_EXPORT_PRIVATE bool IsControlFrame(QuicFrameType type); 150 151 // Returns control_frame_id of |frame|. Returns kInvalidControlFrameId if 152 // |frame| does not have a valid control_frame_id. 153 QUIC_EXPORT_PRIVATE QuicControlFrameId 154 GetControlFrameId(const QuicFrame& frame); 155 156 // Sets control_frame_id of |frame| to |control_frame_id|. 157 QUIC_EXPORT_PRIVATE void SetControlFrameId(QuicControlFrameId control_frame_id, 158 QuicFrame* frame); 159 160 // Returns a copy of |frame|. 161 QUIC_EXPORT_PRIVATE QuicFrame 162 CopyRetransmittableControlFrame(const QuicFrame& frame); 163 164 // Returns a copy of |frame|. 165 QUIC_EXPORT_PRIVATE QuicFrame CopyQuicFrame(QuicBufferAllocator* allocator, 166 const QuicFrame& frame); 167 168 // Returns a copy of |frames|. 169 QUIC_EXPORT_PRIVATE QuicFrames CopyQuicFrames(QuicBufferAllocator* allocator, 170 const QuicFrames& frames); 171 172 // Human-readable description suitable for logging. 173 QUIC_EXPORT_PRIVATE std::string QuicFramesToString(const QuicFrames& frames); 174 175 } // namespace quic 176 177 #endif // QUICHE_QUIC_CORE_FRAMES_QUIC_FRAME_H_ 178