1 /** @file 2 * 3 * A brief file description 4 * 5 * @section license License 6 * 7 * Licensed to the Apache Software Foundation (ASF) under one 8 * or more contributor license agreements. See the NOTICE file 9 * distributed with this work for additional information 10 * regarding copyright ownership. The ASF licenses this file 11 * to you under the Apache License, Version 2.0 (the 12 * "License"); you may not use this file except in compliance 13 * with the License. You may obtain a copy of the License at 14 * 15 * http://www.apache.org/licenses/LICENSE-2.0 16 * 17 * Unless required by applicable law or agreed to in writing, software 18 * distributed under the License is distributed on an "AS IS" BASIS, 19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 20 * See the License for the specific language governing permissions and 21 * limitations under the License. 22 */ 23 24 #pragma once 25 26 #include <memory> 27 #include <yaml-cpp/yaml.h> 28 29 #include "QUICFrame.h" 30 31 namespace QLog 32 { 33 class QLogFrame 34 { 35 public: QLogFrame(QUICFrameType type)36 QLogFrame(QUICFrameType type) : _type(type) {} ~QLogFrame()37 virtual ~QLogFrame() {} 38 39 QUICFrameType type()40 type() const 41 { 42 return this->_type; 43 } 44 45 // encode frame into YAML stype 46 virtual void encode(YAML::Node &node) = 0; 47 48 protected: 49 QUICFrameType _type = QUICFrameType::UNKNOWN; 50 }; 51 52 using QLogFrameUPtr = std::unique_ptr<QLogFrame>; 53 54 // 55 // convert QUICFrame to QLogFrame 56 // 57 class QLogFrameFactory 58 { 59 public: 60 // create QLogFrame 61 static QLogFrameUPtr create(const QUICFrame *frame); 62 }; 63 64 namespace Frame 65 { 66 struct AckFrame : public QLogFrame { AckFrameAckFrame67 AckFrame(const QUICAckFrame &frame) : QLogFrame(frame.type()) 68 { 69 acked_range = frame.ranges(); 70 ack_delay = frame.ack_delay(); 71 if (frame.ecn_section()) { 72 ect0 = frame.ecn_section()->ect0_count(); 73 ect1 = frame.ecn_section()->ect1_count(); 74 ce = frame.ecn_section()->ecn_ce_count(); 75 } 76 } 77 78 void encode(YAML::Node &) override; 79 80 std::set<QUICAckFrame::PacketNumberRange> acked_range; 81 uint64_t ect1 = 0; 82 uint64_t ect0 = 0; 83 uint64_t ce = 0; 84 uint64_t ack_delay = 0; 85 }; 86 87 struct StreamFrame : public QLogFrame { StreamFrameStreamFrame88 StreamFrame(const QUICStreamFrame &frame) : QLogFrame(frame.type()) 89 { 90 stream_id = std::to_string(static_cast<uint64_t>(frame.stream_id())); 91 offset = std::to_string(static_cast<uint64_t>(frame.offset())); 92 length = frame.data_length(); 93 fin = frame.has_fin_flag(); 94 } 95 96 void encode(YAML::Node &) override; 97 std::string stream_id; 98 99 // These two MUST always be set 100 // If not present in the Frame type, log their default values 101 std::string offset; 102 uint64_t length = 0; 103 104 // this MAY be set any time, but MUST only be set if the value is "true" 105 // if absent, the value MUST be assumed to be "false" 106 bool fin = false; 107 108 // FIXME raw 109 }; 110 111 struct PaddingFrame : public QLogFrame { PaddingFramePaddingFrame112 PaddingFrame(const QUICPaddingFrame &frame) : QLogFrame(frame.type()) {} 113 void encode(YAML::Node &) override; 114 }; 115 116 struct PingFrame : public QLogFrame { PingFramePingFrame117 PingFrame(const QUICPingFrame &frame) : QLogFrame(frame.type()) {} 118 void encode(YAML::Node &) override; 119 }; 120 121 struct RstStreamFrame : public QLogFrame { RstStreamFrameRstStreamFrame122 RstStreamFrame(const QUICRstStreamFrame &frame) : QLogFrame(frame.type()) 123 { 124 stream_id = std::to_string(static_cast<uint64_t>(frame.stream_id())); 125 error_code = frame.error_code(); 126 final_size = std::to_string(frame.final_offset()); 127 } 128 129 void encode(YAML::Node &) override; 130 std::string stream_id; 131 // FIXME ApplicationError 132 uint64_t error_code = 0; 133 std::string final_size; 134 }; 135 136 struct StopSendingFrame : public QLogFrame { StopSendingFrameStopSendingFrame137 StopSendingFrame(const QUICStopSendingFrame &frame) : QLogFrame(frame.type()) 138 { 139 stream_id = std::to_string(static_cast<uint64_t>(frame.stream_id())); 140 error_code = frame.error_code(); 141 } 142 143 void encode(YAML::Node &) override; 144 std::string stream_id; 145 // FIXME ApplicationError 146 uint64_t error_code = 0; 147 }; 148 149 struct CryptoFrame : public QLogFrame { CryptoFrameCryptoFrame150 CryptoFrame(const QUICCryptoFrame &frame) : QLogFrame(frame.type()) 151 { 152 offset = std::to_string(static_cast<uint64_t>(frame.offset())); 153 length = frame.data_length(); 154 } 155 156 void encode(YAML::Node &) override; 157 std::string offset; 158 uint64_t length = 0; 159 }; 160 161 struct NewTokenFrame : public QLogFrame { NewTokenFrameNewTokenFrame162 NewTokenFrame(const QUICNewTokenFrame &frame) : QLogFrame(frame.type()) 163 { 164 token = QUICBase::to_hex(frame.token(), frame.token_length()); 165 length = frame.token_length(); 166 } 167 168 void encode(YAML::Node &) override; 169 std::string token; 170 uint64_t length = 0; 171 }; 172 173 struct MaxDataFrame : public QLogFrame { MaxDataFrameMaxDataFrame174 MaxDataFrame(const QUICMaxDataFrame &frame) : QLogFrame(frame.type()), maximum(std::to_string(frame.maximum_data())) {} 175 176 void encode(YAML::Node &) override; 177 std::string maximum; 178 }; 179 180 struct MaxStreamDataFrame : public QLogFrame { MaxStreamDataFrameMaxStreamDataFrame181 MaxStreamDataFrame(const QUICMaxStreamDataFrame &frame) : QLogFrame(frame.type()) 182 { 183 stream_id = std::to_string(static_cast<uint64_t>(frame.stream_id())); 184 maximum = std::to_string(frame.maximum_stream_data()); 185 } 186 187 void encode(YAML::Node &) override; 188 std::string stream_id; 189 std::string maximum; 190 }; 191 192 struct MaxStreamsFrame : public QLogFrame { MaxStreamsFrameMaxStreamsFrame193 MaxStreamsFrame(const QUICMaxStreamsFrame &frame) : QLogFrame(frame.type()) 194 { 195 maximum = std::to_string(frame.maximum_streams()); 196 // FIXME 197 stream_type = "bidirectional"; 198 } 199 200 void encode(YAML::Node &) override; 201 std::string stream_type; 202 std::string maximum; 203 }; 204 205 struct DataBlockedFrame : public QLogFrame { DataBlockedFrameDataBlockedFrame206 DataBlockedFrame(const QUICDataBlockedFrame &frame) : QLogFrame(frame.type()) 207 { 208 limit = std::to_string(static_cast<uint64_t>(frame.offset())); 209 } 210 void encode(YAML::Node &) override; 211 std::string limit; 212 }; 213 214 struct StreamDataBlockedFrame : public QLogFrame { StreamDataBlockedFrameStreamDataBlockedFrame215 StreamDataBlockedFrame(const QUICStreamDataBlockedFrame &frame) : QLogFrame(frame.type()) 216 { 217 limit = std::to_string(static_cast<uint64_t>(frame.offset())); 218 stream_id = std::to_string(static_cast<uint64_t>(frame.stream_id())); 219 } 220 221 void encode(YAML::Node &) override; 222 std::string stream_id, limit; 223 }; 224 225 struct StreamsBlockedFrame : public QLogFrame { StreamsBlockedFrameStreamsBlockedFrame226 StreamsBlockedFrame(const QUICStreamIdBlockedFrame &frame) : QLogFrame(frame.type()) 227 { 228 stream_type = "bidirectional"; 229 stream_id = std::to_string(static_cast<uint64_t>(frame.stream_id())); 230 } 231 232 void encode(YAML::Node &) override; 233 std::string stream_id, stream_type; 234 }; 235 236 struct NewConnectionIDFrame : public QLogFrame { NewConnectionIDFrameNewConnectionIDFrame237 NewConnectionIDFrame(const QUICNewConnectionIdFrame &frame) 238 : QLogFrame(frame.type()), sequence_number(std::to_string(frame.sequence())) 239 { 240 retire_prior_to = std::to_string(frame.retire_prior_to()); 241 connection_id = frame.connection_id().hex(); 242 stateless_reset_token = QUICBase::to_hex(frame.stateless_reset_token().buf(), QUICStatelessResetToken::LEN); 243 length = frame.connection_id().length(); 244 } 245 246 void encode(YAML::Node &) override; 247 std::string sequence_number, retire_prior_to, connection_id, stateless_reset_token; 248 uint8_t length = 0; 249 }; 250 251 struct RetireConnectionIDFrame : public QLogFrame { RetireConnectionIDFrameRetireConnectionIDFrame252 RetireConnectionIDFrame(const QUICRetireConnectionIdFrame &frame) 253 : QLogFrame(frame.type()), sequence_number(std::to_string(frame.seq_num())) 254 { 255 } 256 void encode(YAML::Node &) override; 257 std::string sequence_number; 258 }; 259 260 struct PathChallengeFrame : public QLogFrame { PathChallengeFramePathChallengeFrame261 PathChallengeFrame(const QUICPathChallengeFrame &frame) 262 : QLogFrame(frame.type()), data(QUICBase::to_hex(frame.data(), QUICPathChallengeFrame::DATA_LEN)) 263 { 264 } 265 void encode(YAML::Node &) override; 266 std::string data; 267 }; 268 269 struct PathResponseFrame : public QLogFrame { PathResponseFramePathResponseFrame270 PathResponseFrame(const QUICPathResponseFrame &frame) 271 : QLogFrame(frame.type()), data(QUICBase::to_hex(frame.data(), QUICPathChallengeFrame::DATA_LEN)) 272 { 273 } 274 void encode(YAML::Node &) override; 275 std::string data; 276 }; 277 278 struct ConnectionCloseFrame : public QLogFrame { 279 ConnectionCloseFrame(const QUICConnectionCloseFrame &frame, bool app = false) 280 : QLogFrame(frame.type()), error_space(app ? "application" : "transport") 281 { 282 error_code = frame.error_code(); 283 // FIXME 284 raw_error_code = error_code; 285 reason = frame.reason_phrase(); 286 } 287 288 void encode(YAML::Node &) override; 289 std::string error_space, reason, trigger_frame_type; 290 uint64_t error_code, raw_error_code; 291 }; 292 293 struct HandshakeDoneFrame : public QLogFrame { HandshakeDoneFrameHandshakeDoneFrame294 HandshakeDoneFrame(const QUICHandshakeDoneFrame &frame) : QLogFrame(frame.type()){}; 295 void encode(YAML::Node &) override; 296 }; 297 298 struct UnknownFrame : public QLogFrame { UnknownFrameUnknownFrame299 UnknownFrame(const QUICUnknownFrame &frame) : QLogFrame(frame.type()) 300 { 301 // FIXME 302 raw_frame_type = static_cast<uint8_t>(frame.type()); 303 } 304 305 void encode(YAML::Node &) override; 306 uint8_t raw_frame_type = 0; 307 }; 308 } // namespace Frame 309 } // namespace QLog 310