aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/core/manifest_format_fixed.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/src/core/manifest_format_fixed.cc')
-rw-r--r--libtransport/src/core/manifest_format_fixed.cc370
1 files changed, 245 insertions, 125 deletions
diff --git a/libtransport/src/core/manifest_format_fixed.cc b/libtransport/src/core/manifest_format_fixed.cc
index 11d4a56cb..bda666c0c 100644
--- a/libtransport/src/core/manifest_format_fixed.cc
+++ b/libtransport/src/core/manifest_format_fixed.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2017-2019 Cisco and/or its affiliates.
+ * Copyright (c) 2021-2022 Cisco and/or its affiliates.
* Licensed 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:
@@ -18,211 +18,331 @@
#include <hicn/transport/utils/literals.h>
namespace transport {
-
namespace core {
-// TODO use preallocated pool of membufs
-FixedManifestEncoder::FixedManifestEncoder(Packet &packet,
- std::size_t signature_size,
- bool clear)
+// ---------------------------------------------------------
+// FixedManifest
+// ---------------------------------------------------------
+size_t FixedManifest::manifestHeaderSize(
+ interface::ProductionProtocolAlgorithms transport_type) {
+ uint32_t params_size = 0;
+
+ switch (transport_type) {
+ case interface::ProductionProtocolAlgorithms::BYTE_STREAM:
+ params_size = MANIFEST_PARAMS_BYTESTREAM_SIZE;
+ break;
+ case interface::ProductionProtocolAlgorithms::RTC_PROD:
+ params_size = MANIFEST_PARAMS_RTC_SIZE;
+ break;
+ default:
+ break;
+ }
+
+ return MANIFEST_META_SIZE + MANIFEST_ENTRY_META_SIZE + params_size;
+}
+
+size_t FixedManifest::manifestPayloadSize(size_t nb_entries) {
+ return nb_entries * MANIFEST_ENTRY_SIZE;
+}
+
+// ---------------------------------------------------------
+// FixedManifestEncoder
+// ---------------------------------------------------------
+FixedManifestEncoder::FixedManifestEncoder(Packet::Ptr packet, bool clear)
: packet_(packet),
- max_size_(Packet::default_mtu - packet_.headerSize()),
- manifest_header_(reinterpret_cast<ManifestHeader *>(
- packet_.writableData() + packet_.headerSize())),
- manifest_entries_(
- reinterpret_cast<ManifestEntry *>(manifest_header_ + 1)),
- current_entry_(0),
- signature_size_(signature_size) {
+ transport_type_(interface::ProductionProtocolAlgorithms::UNKNOWN),
+ encoded_(false) {
+ manifest_meta_ = reinterpret_cast<ManifestMeta *>(packet_->writableData() +
+ packet_->headerSize());
+ manifest_entry_meta_ =
+ reinterpret_cast<ManifestEntryMeta *>(manifest_meta_ + 1);
+
if (clear) {
- *manifest_header_ = {0};
+ *manifest_meta_ = {0};
+ *manifest_entry_meta_ = {0};
}
}
FixedManifestEncoder::~FixedManifestEncoder() {}
FixedManifestEncoder &FixedManifestEncoder::encodeImpl() {
- packet_.append(sizeof(ManifestHeader) +
- manifest_header_->number_of_entries * sizeof(ManifestEntry));
- packet_.updateLength();
+ if (encoded_) {
+ return *this;
+ }
+
+ // Copy manifest header
+ manifest_meta_->transport_type = static_cast<uint8_t>(transport_type_);
+ manifest_entry_meta_->nb_entries = manifest_entries_.size();
+
+ packet_->append(manifestHeaderSizeImpl());
+
+ packet_->updateLength();
+ auto params = reinterpret_cast<uint8_t *>(manifest_entry_meta_ + 1);
+
+ switch (transport_type_) {
+ case interface::ProductionProtocolAlgorithms::BYTE_STREAM: {
+ auto bytestream = reinterpret_cast<const uint8_t *>(&params_bytestream_);
+ std::memcpy(params, bytestream, MANIFEST_PARAMS_BYTESTREAM_SIZE);
+ break;
+ }
+ case interface::ProductionProtocolAlgorithms::RTC_PROD: {
+ auto rtc = reinterpret_cast<const uint8_t *>(&params_rtc_);
+ std::memcpy(params, rtc, MANIFEST_PARAMS_RTC_SIZE);
+ break;
+ }
+ default:
+ break;
+ }
+
+ // Copy manifest entries
+ auto payload = reinterpret_cast<const uint8_t *>(manifest_entries_.data());
+ packet_->appendPayload(payload, manifestPayloadSizeImpl());
+
+ packet_->updateLength();
+ if (TRANSPORT_EXPECT_FALSE(packet_->payloadSize() < manifestSizeImpl())) {
+ throw errors::RuntimeException("Error encoding the manifest");
+ }
+
+ encoded_ = true;
return *this;
}
FixedManifestEncoder &FixedManifestEncoder::clearImpl() {
- packet_.trimEnd(sizeof(ManifestHeader) +
- manifest_header_->number_of_entries * sizeof(ManifestEntry));
- current_entry_ = 0;
- *manifest_header_ = {0};
+ if (encoded_) {
+ packet_->trimEnd(manifestSizeImpl());
+ }
+
+ transport_type_ = interface::ProductionProtocolAlgorithms::UNKNOWN;
+ encoded_ = false;
+ *manifest_meta_ = {0};
+ *manifest_entry_meta_ = {0};
+ params_bytestream_ = {0};
+ params_rtc_ = {0};
+ manifest_entries_.clear();
+
return *this;
}
-FixedManifestEncoder &FixedManifestEncoder::setHashAlgorithmImpl(
- auth::CryptoHashType algorithm) {
- manifest_header_->hash_algorithm = static_cast<uint8_t>(algorithm);
+bool FixedManifestEncoder::isEncodedImpl() const { return encoded_; }
+
+FixedManifestEncoder &FixedManifestEncoder::setTypeImpl(
+ ManifestType manifest_type) {
+ manifest_meta_->type = static_cast<uint8_t>(manifest_type);
return *this;
}
-FixedManifestEncoder &FixedManifestEncoder::setManifestTypeImpl(
- ManifestType manifest_type) {
- manifest_header_->manifest_type = static_cast<uint8_t>(manifest_type);
+FixedManifestEncoder &FixedManifestEncoder::setMaxCapacityImpl(
+ uint8_t max_capacity) {
+ manifest_meta_->max_capacity = max_capacity;
+ return *this;
+}
+
+FixedManifestEncoder &FixedManifestEncoder::setHashAlgorithmImpl(
+ auth::CryptoHashType algorithm) {
+ manifest_meta_->hash_algorithm = static_cast<uint8_t>(algorithm);
return *this;
}
-FixedManifestEncoder &
-FixedManifestEncoder::setNextSegmentCalculationStrategyImpl(
- NextSegmentCalculationStrategy strategy) {
- manifest_header_->next_segment_strategy = static_cast<uint8_t>(strategy);
+FixedManifestEncoder &FixedManifestEncoder::setIsLastImpl(bool is_last) {
+ manifest_meta_->is_last = static_cast<uint8_t>(is_last);
return *this;
}
FixedManifestEncoder &FixedManifestEncoder::setBaseNameImpl(
const core::Name &base_name) {
- base_name.copyToDestination(
- reinterpret_cast<uint8_t *>(&manifest_header_->prefix[0]), false);
- manifest_header_->flags.ipv6 =
+ manifest_entry_meta_->is_ipv6 =
base_name.getAddressFamily() == AF_INET6 ? 1_U8 : 0_U8;
+ base_name.copyPrefixToDestination(
+ reinterpret_cast<uint8_t *>(&manifest_entry_meta_->prefix[0]));
return *this;
}
-FixedManifestEncoder &FixedManifestEncoder::addSuffixAndHashImpl(
- uint32_t suffix, const auth::CryptoHash &hash) {
- auto _hash = hash.getDigest();
- addSuffixHashBytes(suffix, _hash.data(), _hash.size());
+FixedManifestEncoder &FixedManifestEncoder::setParamsBytestreamImpl(
+ const ParamsBytestream &params) {
+ transport_type_ = interface::ProductionProtocolAlgorithms::BYTE_STREAM;
+ params_bytestream_ = TransportParamsBytestream{
+ .final_segment = params.final_segment,
+ };
return *this;
}
-void FixedManifestEncoder::addSuffixHashBytes(uint32_t suffix,
- const uint8_t *hash,
- std::size_t length) {
- manifest_entries_[current_entry_].suffix = htonl(suffix);
- // std::copy(hash, hash + length,
- // manifest_entries_[current_entry_].hash);
- std::memcpy(
- reinterpret_cast<uint8_t *>(manifest_entries_[current_entry_].hash), hash,
- length);
+FixedManifestEncoder &FixedManifestEncoder::setParamsRTCImpl(
+ const ParamsRTC &params) {
+ transport_type_ = interface::ProductionProtocolAlgorithms::RTC_PROD;
+ params_rtc_ = TransportParamsRTC{
+ .timestamp = params.timestamp,
+ .prod_rate = params.prod_rate,
+ .prod_seg = params.prod_seg,
+ .fec_type = static_cast<uint32_t>(params.fec_type),
+ };
+ return *this;
+}
- manifest_header_->number_of_entries++;
- current_entry_++;
+FixedManifestEncoder &FixedManifestEncoder::addEntryImpl(
+ uint32_t suffix, const auth::CryptoHash &hash) {
+ ManifestEntry last_entry = {
+ .suffix = portability::host_to_net(suffix),
+ .hash = {0},
+ };
- if (TRANSPORT_EXPECT_FALSE(estimateSerializedLengthImpl() > max_size_)) {
- throw errors::RuntimeException("Manifest size exceeded the packet MTU!");
- }
-}
+ auto last_hash = reinterpret_cast<uint8_t *>(last_entry.hash);
+ std::memcpy(last_hash, hash.getDigest()->data(), hash.getSize());
-FixedManifestEncoder &FixedManifestEncoder::setIsFinalManifestImpl(
- bool is_last) {
- manifest_header_->flags.is_last = static_cast<uint8_t>(is_last);
+ manifest_entries_.push_back(last_entry);
return *this;
}
-FixedManifestEncoder &FixedManifestEncoder::setVersionImpl(
- ManifestVersion version) {
- manifest_header_->version = static_cast<uint8_t>(version);
+FixedManifestEncoder &FixedManifestEncoder::removeEntryImpl(uint32_t suffix) {
+ for (auto it = manifest_entries_.begin(); it != manifest_entries_.end();) {
+ if (it->suffix == suffix)
+ it = manifest_entries_.erase(it);
+ else
+ ++it;
+ }
return *this;
}
-std::size_t FixedManifestEncoder::estimateSerializedLengthImpl(
- std::size_t additional_entries) {
- return sizeof(ManifestHeader) +
- (manifest_header_->number_of_entries + additional_entries) *
- sizeof(ManifestEntry);
+size_t FixedManifestEncoder::manifestHeaderSizeImpl() const {
+ return FixedManifest::manifestHeaderSize(transport_type_);
}
-FixedManifestEncoder &FixedManifestEncoder::updateImpl() {
- max_size_ = Packet::default_mtu - packet_.headerSize() - signature_size_;
- return *this;
+size_t FixedManifestEncoder::manifestPayloadSizeImpl(
+ size_t additional_entries) const {
+ return FixedManifest::manifestPayloadSize(manifest_entries_.size() +
+ additional_entries);
}
-FixedManifestEncoder &FixedManifestEncoder::setFinalBlockNumberImpl(
- std::uint32_t final_block_number) {
- manifest_header_->final_block_number = htonl(final_block_number);
- return *this;
+size_t FixedManifestEncoder::manifestSizeImpl(size_t additional_entries) const {
+ return manifestHeaderSizeImpl() + manifestPayloadSizeImpl(additional_entries);
}
-std::size_t FixedManifestEncoder::getManifestHeaderSizeImpl() {
- return sizeof(ManifestHeader);
+// ---------------------------------------------------------
+// FixedManifestDecoder
+// ---------------------------------------------------------
+FixedManifestDecoder::FixedManifestDecoder(Packet::Ptr packet)
+ : packet_(packet), decoded_(false) {
+ manifest_meta_ =
+ reinterpret_cast<ManifestMeta *>(packet_->getPayload()->writableData());
+ manifest_entry_meta_ =
+ reinterpret_cast<ManifestEntryMeta *>(manifest_meta_ + 1);
}
-std::size_t FixedManifestEncoder::getManifestEntrySizeImpl() {
- return sizeof(ManifestEntry);
-}
-
-FixedManifestDecoder::FixedManifestDecoder(Packet &packet)
- : packet_(packet),
- manifest_header_(reinterpret_cast<ManifestHeader *>(
- packet_.getPayload()->writableData())),
- manifest_entries_(reinterpret_cast<ManifestEntry *>(
- packet_.getPayload()->writableData() + sizeof(ManifestHeader))) {}
-
FixedManifestDecoder::~FixedManifestDecoder() {}
-void FixedManifestDecoder::decodeImpl() {
- std::size_t packet_size = packet_.payloadSize();
+FixedManifestDecoder &FixedManifestDecoder::decodeImpl() {
+ if (decoded_) {
+ return *this;
+ }
- if (packet_size < sizeof(ManifestHeader) ||
- packet_size < estimateSerializedLengthImpl()) {
+ if (packet_->payloadSize() < manifestSizeImpl()) {
throw errors::RuntimeException(
- "The packet does not match expected manifest size.");
+ "The packet payload size does not match expected manifest size");
}
-}
-FixedManifestDecoder &FixedManifestDecoder::clearImpl() { return *this; }
+ switch (getTransportTypeImpl()) {
+ case interface::ProductionProtocolAlgorithms::BYTE_STREAM:
+ params_bytestream_ = reinterpret_cast<TransportParamsBytestream *>(
+ manifest_entry_meta_ + 1);
+ manifest_entries_ =
+ reinterpret_cast<ManifestEntry *>(params_bytestream_ + 1);
+ break;
+ case interface::ProductionProtocolAlgorithms::RTC_PROD:
+ params_rtc_ =
+ reinterpret_cast<TransportParamsRTC *>(manifest_entry_meta_ + 1);
+ manifest_entries_ = reinterpret_cast<ManifestEntry *>(params_rtc_ + 1);
+ break;
+ default:
+ manifest_entries_ =
+ reinterpret_cast<ManifestEntry *>(manifest_entry_meta_ + 1);
+ break;
+ }
-ManifestType FixedManifestDecoder::getManifestTypeImpl() const {
- return static_cast<ManifestType>(manifest_header_->manifest_type);
+ decoded_ = true;
+ return *this;
}
-auth::CryptoHashType FixedManifestDecoder::getHashAlgorithmImpl() const {
- return static_cast<auth::CryptoHashType>(manifest_header_->hash_algorithm);
+FixedManifestDecoder &FixedManifestDecoder::clearImpl() {
+ decoded_ = false;
+ return *this;
}
-NextSegmentCalculationStrategy
-FixedManifestDecoder::getNextSegmentCalculationStrategyImpl() const {
- return static_cast<NextSegmentCalculationStrategy>(
- manifest_header_->next_segment_strategy);
+bool FixedManifestDecoder::isDecodedImpl() const { return decoded_; }
+
+ManifestType FixedManifestDecoder::getTypeImpl() const {
+ return static_cast<ManifestType>(manifest_meta_->type);
}
-typename Fixed::SuffixList FixedManifestDecoder::getSuffixHashListImpl() {
- typename Fixed::SuffixList hash_list;
+interface::ProductionProtocolAlgorithms
+FixedManifestDecoder::getTransportTypeImpl() const {
+ return static_cast<interface::ProductionProtocolAlgorithms>(
+ manifest_meta_->transport_type);
+}
- for (int i = 0; i < manifest_header_->number_of_entries; i++) {
- hash_list.insert(hash_list.end(),
- std::make_pair(ntohl(manifest_entries_[i].suffix),
- reinterpret_cast<uint8_t *>(
- &manifest_entries_[i].hash[0])));
- }
+uint8_t FixedManifestDecoder::getMaxCapacityImpl() const {
+ return manifest_meta_->max_capacity;
+}
- return hash_list;
+auth::CryptoHashType FixedManifestDecoder::getHashAlgorithmImpl() const {
+ return static_cast<auth::CryptoHashType>(manifest_meta_->hash_algorithm);
+}
+
+bool FixedManifestDecoder::getIsLastImpl() const {
+ return static_cast<bool>(manifest_meta_->is_last);
}
core::Name FixedManifestDecoder::getBaseNameImpl() const {
- if (static_cast<bool>(manifest_header_->flags.ipv6)) {
- return core::Name(AF_INET6,
- reinterpret_cast<uint8_t *>(&manifest_header_->prefix));
+ if (static_cast<bool>(manifest_entry_meta_->is_ipv6)) {
+ return core::Name(
+ AF_INET6, reinterpret_cast<uint8_t *>(&manifest_entry_meta_->prefix));
} else {
- return core::Name(AF_INET,
- reinterpret_cast<uint8_t *>(&manifest_header_->prefix));
+ return core::Name(
+ AF_INET, reinterpret_cast<uint8_t *>(&manifest_entry_meta_->prefix));
}
}
-bool FixedManifestDecoder::getIsFinalManifestImpl() const {
- return static_cast<bool>(manifest_header_->flags.is_last);
+ParamsBytestream FixedManifestDecoder::getParamsBytestreamImpl() const {
+ return ParamsBytestream{
+ .final_segment = params_bytestream_->final_segment,
+ };
+}
+
+ParamsRTC FixedManifestDecoder::getParamsRTCImpl() const {
+ return ParamsRTC{
+ .timestamp = params_rtc_->timestamp,
+ .prod_rate = params_rtc_->prod_rate,
+ .prod_seg = params_rtc_->prod_seg,
+ .fec_type = static_cast<protocol::fec::FECType>(params_rtc_->fec_type),
+ };
}
-ManifestVersion FixedManifestDecoder::getVersionImpl() const {
- return static_cast<ManifestVersion>(manifest_header_->version);
+typename Fixed::SuffixList FixedManifestDecoder::getEntriesImpl() const {
+ typename Fixed::SuffixList hash_list;
+
+ for (int i = 0; i < manifest_entry_meta_->nb_entries; i++) {
+ hash_list.insert(
+ hash_list.end(),
+ std::make_pair(
+ portability::net_to_host(manifest_entries_[i].suffix),
+ reinterpret_cast<uint8_t *>(&manifest_entries_[i].hash[0])));
+ }
+
+ return hash_list;
}
-std::size_t FixedManifestDecoder::estimateSerializedLengthImpl(
- std::size_t additional_entries) const {
- return sizeof(ManifestHeader) +
- (additional_entries + manifest_header_->number_of_entries) *
- sizeof(ManifestEntry);
+size_t FixedManifestDecoder::manifestHeaderSizeImpl() const {
+ interface::ProductionProtocolAlgorithms type = getTransportTypeImpl();
+ return FixedManifest::manifestHeaderSize(type);
}
-uint32_t FixedManifestDecoder::getFinalBlockNumberImpl() const {
- return ntohl(manifest_header_->final_block_number);
+size_t FixedManifestDecoder::manifestPayloadSizeImpl(
+ size_t additional_entries) const {
+ size_t nb_entries = manifest_entry_meta_->nb_entries + additional_entries;
+ return FixedManifest::manifestPayloadSize(nb_entries);
}
-} // end namespace core
+size_t FixedManifestDecoder::manifestSizeImpl(size_t additional_entries) const {
+ return manifestHeaderSizeImpl() + manifestPayloadSizeImpl(additional_entries);
+}
+} // end namespace core
} // end namespace transport