blob: bcc46fcf7396cfdcd0de6e837d0c8bd2413f8066 [file] [log] [blame]
/** @file
*
* A brief file description
*
* @section license License
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "QLogFrame.h"
namespace QLog
{
template <typename Real>
const Real &
Convert(const QUICFrame *frame)
{
// FIXME: dangerous
auto tmp = static_cast<const QUICFrame *>(frame);
#if defined(DEBUG)
auto ref = dynamic_cast<const Real *>(tmp);
ink_assert(ref != nullptr);
return *ref;
#endif
return *static_cast<const Real *>(tmp);
}
QLogFrameUPtr
QLogFrameFactory::create(const QUICFrame *frame)
{
switch (frame->type()) {
case QUICFrameType::ACK:
return std::make_unique<Frame::AckFrame>(Convert<QUICAckFrame>(frame));
case QUICFrameType::PADDING:
return std::make_unique<Frame::PaddingFrame>(Convert<QUICPaddingFrame>(frame));
case QUICFrameType::PING:
return std::make_unique<Frame::PingFrame>(Convert<QUICPingFrame>(frame));
case QUICFrameType::RESET_STREAM:
return std::make_unique<Frame::RstStreamFrame>(Convert<QUICRstStreamFrame>(frame));
case QUICFrameType::STOP_SENDING:
return std::make_unique<Frame::StopSendingFrame>(Convert<QUICStopSendingFrame>(frame));
case QUICFrameType::CRYPTO:
return std::make_unique<Frame::CryptoFrame>(Convert<QUICCryptoFrame>(frame));
case QUICFrameType::NEW_TOKEN:
return std::make_unique<Frame::NewTokenFrame>(Convert<QUICNewTokenFrame>(frame));
case QUICFrameType::STREAM:
return std::make_unique<Frame::StreamFrame>(Convert<QUICStreamFrame>(frame));
case QUICFrameType::MAX_DATA:
return std::make_unique<Frame::MaxDataFrame>(Convert<QUICMaxDataFrame>(frame));
case QUICFrameType::MAX_STREAM_DATA:
return std::make_unique<Frame::MaxStreamDataFrame>(Convert<QUICMaxStreamDataFrame>(frame));
case QUICFrameType::MAX_STREAMS:
return std::make_unique<Frame::MaxStreamsFrame>(Convert<QUICMaxStreamsFrame>(frame));
case QUICFrameType::DATA_BLOCKED:
return std::make_unique<Frame::DataBlockedFrame>(Convert<QUICDataBlockedFrame>(frame));
case QUICFrameType::STREAM_DATA_BLOCKED:
return std::make_unique<Frame::StreamDataBlockedFrame>(Convert<QUICStreamDataBlockedFrame>(frame));
case QUICFrameType::STREAMS_BLOCKED:
return std::make_unique<Frame::StreamsBlockedFrame>(Convert<QUICStreamIdBlockedFrame>(frame));
case QUICFrameType::NEW_CONNECTION_ID:
return std::make_unique<Frame::NewConnectionIDFrame>(Convert<QUICNewConnectionIdFrame>(frame));
case QUICFrameType::RETIRE_CONNECTION_ID:
return std::make_unique<Frame::RetireConnectionIDFrame>(Convert<QUICRetireConnectionIdFrame>(frame));
case QUICFrameType::PATH_CHALLENGE:
return std::make_unique<Frame::PathChallengeFrame>(Convert<QUICPathChallengeFrame>(frame));
case QUICFrameType::PATH_RESPONSE:
return std::make_unique<Frame::PathResponseFrame>(Convert<QUICPathResponseFrame>(frame));
case QUICFrameType::CONNECTION_CLOSE:
return std::make_unique<Frame::ConnectionCloseFrame>(Convert<QUICConnectionCloseFrame>(frame));
case QUICFrameType::HANDSHAKE_DONE:
return std::make_unique<Frame::HandshakeDoneFrame>(Convert<QUICHandshakeDoneFrame>(frame));
default:
ink_release_assert(0);
return nullptr;
}
}
namespace Frame
{
template <typename T>
std::string
convert_to_string(T a)
{
return std::to_string(static_cast<uint64_t>(a));
}
void
AckFrame::encode(YAML::Node &node)
{
node["frame_type"] = "ack";
node["ack_delay"] = std::to_string(ack_delay);
for (auto &it : acked_range) {
YAML::Node sub;
sub.push_back(convert_to_string(it.first()));
sub.push_back(convert_to_string(it.last()));
node["acked_ranges"].push_back(sub);
}
if (ect1) {
node["ect1"] = ect1;
}
if (ect1) {
node["ect0"] = ect0;
}
if (ce) {
node["ce"] = ce;
}
}
void
StreamFrame::encode(YAML::Node &node)
{
node["frame_type"] = "stream";
node["stream_id"] = stream_id;
node["offset"] = offset;
node["length"] = length;
node["fin"] = fin;
}
void
PaddingFrame::encode(YAML::Node &node)
{
node["frame_type"] = "padding";
}
void
PingFrame::encode(YAML::Node &node)
{
node["frame_type"] = "ping";
}
void
RstStreamFrame::encode(YAML::Node &node)
{
node["frame_type"] = "reset_stream";
node["stream_id"] = stream_id;
node["error_code"] = error_code;
node["final_size"] = final_size;
}
void
StopSendingFrame::encode(YAML::Node &node)
{
node["frame_type"] = "stop_sending";
node["stream_id"] = stream_id;
node["error_code"] = error_code;
}
void
CryptoFrame::encode(YAML::Node &node)
{
node["frame_type"] = "crypto";
node["offset"] = offset;
node["length"] = length;
}
void
NewTokenFrame::encode(YAML::Node &node)
{
node["frame_type"] = "new_token";
node["token"] = token;
node["length"] = length;
}
void
MaxDataFrame::encode(YAML::Node &node)
{
node["frame_type"] = "max_data";
node["maximum"] = maximum;
}
void
MaxStreamDataFrame::encode(YAML::Node &node)
{
node["frame_type"] = "max_stream_data";
node["maximum"] = maximum;
node["stream_id"] = stream_id;
}
void
MaxStreamsFrame::encode(YAML::Node &node)
{
node["frame_type"] = "max_streams";
node["maximum"] = maximum;
node["stream_type"] = stream_type;
}
void
DataBlockedFrame::encode(YAML::Node &node)
{
node["frame_type"] = "data_blocked";
node["limit"] = limit;
}
void
StreamDataBlockedFrame::encode(YAML::Node &node)
{
node["frame_type"] = "stream_data_blocked";
node["limit"] = limit;
node["stream_id"] = stream_id;
}
void
StreamsBlockedFrame::encode(YAML::Node &node)
{
node["frame_type"] = "streams_blocked";
node["stream_id"] = stream_id;
node["stream_type"] = stream_type;
}
void
NewConnectionIDFrame::encode(YAML::Node &node)
{
node["frame_type"] = "new_connection_id";
node["sequence_number"] = sequence_number;
node["retire_prior_to"] = retire_prior_to;
node["stateless_reset_token"] = stateless_reset_token;
node["length"] = length;
}
void
RetireConnectionIDFrame::encode(YAML::Node &node)
{
node["frame_type"] = "retire_connection_id";
node["sequence_number"] = sequence_number;
}
void
PathChallengeFrame::encode(YAML::Node &node)
{
node["frame_type"] = "path_challenge";
node["data"] = data;
}
void
PathResponseFrame::encode(YAML::Node &node)
{
node["frame_type"] = "path_response";
node["data"] = data;
}
void
ConnectionCloseFrame::encode(YAML::Node &node)
{
node["frame_type"] = "connection_close";
node["error_space"] = error_space;
node["error_code"] = error_code;
node["raw_error_code"] = raw_error_code;
node["reason"] = reason;
}
void
HandshakeDoneFrame::encode(YAML::Node &node)
{
node["frame_type"] = "handshake_done";
}
void
UnknownFrame::encode(YAML::Node &node)
{
node["frame_type"] = "unknown";
node["raw_frame_type"] = raw_frame_type;
}
} // namespace Frame
} // namespace QLog