diff options
Diffstat (limited to 'libtransport/src/protocols/rtc.h')
-rw-r--r-- | libtransport/src/protocols/rtc.h | 227 |
1 files changed, 227 insertions, 0 deletions
diff --git a/libtransport/src/protocols/rtc.h b/libtransport/src/protocols/rtc.h new file mode 100644 index 000000000..f15cdd1eb --- /dev/null +++ b/libtransport/src/protocols/rtc.h @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2017-2019 Cisco and/or its affiTC_SYNC_STATE + * 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: + * + * 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. + */ + +#pragma once + +#include <protocols/datagram_reassembly.h> +#include <protocols/protocol.h> +#include <protocols/rtc_data_path.h> + +#include <map> +#include <queue> +#include <unordered_map> + +// algorithm state +#define HICN_RTC_SYNC_STATE 0 +#define HICN_RTC_NORMAL_STATE 1 +#define HICN_ROUNDS_IN_SYNC_BEFORE_SWITCH 3 + +// packet constants +#define HICN_INIT_PACKET_SIZE 1300 // bytes +#define HICN_PACKET_HEADER_SIZE 60 // bytes ipv6+tcp +#define HICN_NACK_HEADER_SIZE 8 // bytes +#define HICN_TIMESTAMP_SIZE 8 // bytes +#define HICN_RTC_INTEREST_LIFETIME 1000 // ms + +// rtt measurement +// normal interests for data goes from 0 to +// HICN_MIN_PROBE_SEQ, the rest is reserverd for +// probes +#define HICN_MIN_PROBE_SEQ 0xefffffff +#define HICN_MAX_PROBE_SEQ 0xffffffff + +// controller constant +#define HICN_ROUND_LEN \ + 200 // ms interval of time on which + // we take decisions / measurements +#define HICN_MAX_RTX 10 +#define HICN_MAX_RTX_SIZE 1024 +#define HICN_MAX_RTX_MAX_AGE 10000 +#define HICN_MIN_RTT_WIN 30 // rounds +#define HICN_MIN_INTER_ARRIVAL_GAP 100 // ms + +// cwin +#define HICN_INITIAL_CWIN 1 // packets +#define HICN_INITIAL_CWIN_MAX 100000 // packets +#define HICN_MIN_CWIN 10 // packets +#define HICN_WIN_INCREASE_FACTOR 1.5 +#define HICN_WIN_DECREASE_FACTOR 0.9 + +// statistics constants +#define HICN_BANDWIDTH_SLACK_FACTOR 1.8 +#define HICN_ESTIMATED_BW_ALPHA 0.7 +#define HICN_ESTIMATED_PACKET_SIZE 0.7 +#define HICN_ESTIMATED_LOSSES_ALPHA 0.8 +#define HICN_INTEREST_LIFETIME_REDUCTION_FACTOR 0.8 + +// other constants +#define HICN_NANO_IN_A_SEC 1000000000 +#define HICN_MICRO_IN_A_SEC 1000000 +#define HICN_MILLI_IN_A_SEC 1000 + +namespace transport { + +namespace protocol { + +enum packetState { sent_, nacked_, received_, timeout1_, timeout2_, lost_ }; + +typedef enum packetState packetState_t; + +struct sentInterest { + uint64_t transmissionTime; + uint32_t sequence; // sequence number of the interest sent + // to handle seq % buffer_size + packetState_t state; // see packet state +}; + +class RTCTransportProtocol : public TransportProtocol, + public DatagramReassembly { + public: + RTCTransportProtocol(implementation::ConsumerSocket *icnet_socket); + + ~RTCTransportProtocol(); + + int start() override; + + void stop() override; + + void resume() override; + + bool verifyKeyPackets() override; + + private: + // algo functions + void reset() override; + + // CC functions + void updateDelayStats(const ContentObject &content_object); + void updateStats(uint32_t round_duration); + void updateCCState(); + void computeMaxWindow(uint32_t productionRate, uint32_t BDPWin); + void updateWindow(); + void decreaseWindow(); + void increaseWindow(); + void resetPreviousWindow(); + + // packet functions + void sendInterest(Name *interest_name, bool rtx); + void scheduleNextInterests() override; + void sentinelTimer(); + void addRetransmissions(uint32_t val); + void addRetransmissions(uint32_t start, uint32_t stop); + uint64_t retransmit(); + void checkRtx(); + void probeRtt(); + void newRound(); + void onTimeout(Interest::Ptr &&interest) override; + bool onNack(const ContentObject &content_object, bool rtx); + void onContentObject(Interest::Ptr &&interest, + ContentObject::Ptr &&content_object) override; + void onPacketDropped(Interest::Ptr &&interest, + ContentObject::Ptr &&content_object) override {} + void onReassemblyFailed(std::uint32_t missing_segment) override {} + + TRANSPORT_ALWAYS_INLINE virtual void reassemble( + ContentObject::Ptr &&content_object) override { + auto read_buffer = content_object->getPayload(); + read_buffer->trimStart(HICN_TIMESTAMP_SIZE); + Reassembly::read_buffer_ = std::move(read_buffer); + Reassembly::notifyApplication(); + } + + // controller var + std::unique_ptr<asio::steady_timer> round_timer_; + unsigned currentState_; + + // cwin var + uint32_t currentCWin_; + uint32_t maxCWin_; + + // names/packets var + uint32_t actualSegment_; + uint32_t inflightInterestsCount_; + // map seq to rtx + std::map<uint32_t, uint8_t> interestRetransmissions_; + bool rtx_timer_used_; + std::unique_ptr<asio::steady_timer> rtx_timer_; + std::vector<sentInterest> inflightInterests_; + uint32_t lastSegNacked_; // indicates the segment id in the last received + // past Nack. we do not ask for retransmissions + // for samething that is older than this value. + uint32_t lastReceived_; // segment of the last content object received + // indicates the base of the window on the client + uint64_t lastReceivedTime_; // time at which we recevied the + // lastReceived_ packet + + // sentinel + // if all packets in the window get lost we need something that + // wakes up our consumer socket. Interest timeouts set to 1 sec + // expire too late. This timers expire much sooner and if it + // detects that all the interest in the window may be lost + // it sends all of them again + std::unique_ptr<asio::steady_timer> sentinel_timer_; + uint64_t lastEvent_; // time at which we removed a pending + // interest from the window + std::unordered_map<uint32_t, uint8_t> packets_in_window_; + + // rtt probes + // the RTC transport tends to overestimate the RTT + // du to the production time on the server side + // once per second we send an interest for wich we know + // we will get a nack. This nack will keep our estimation + // close to the reality + std::unique_ptr<asio::steady_timer> probe_timer_; + uint64_t time_sent_probe_; + uint32_t probe_seq_number_; + bool received_probe_; + + uint32_t modMask_; + + // stats + bool firstPckReceived_; + uint32_t receivedBytes_; + uint32_t sentInterest_; + uint32_t receivedData_; + int32_t packetLost_; + int32_t lossRecovered_; + uint32_t firstSequenceInRound_; + uint32_t highestReceived_; + double avgPacketSize_; + bool gotNack_; + uint32_t gotFutureNack_; + uint32_t rounds_; + uint32_t roundsWithoutNacks_; + + // we keep track of up two paths (if only one path is in use + // the two values in the vector will be the same) + // position 0 stores the path with minRTT + // position 1 stores the path with maxRTT + uint32_t producerPathLabels_[2]; + + std::unordered_map<uint32_t, std::shared_ptr<RTCDataPath>> pathTable_; + uint32_t roundCounter_; + + // CC var + double estimatedBw_; + double lossRate_; + double queuingDelay_; + unsigned protocolState_; + + bool initied; +}; + +} // namespace protocol + +} // namespace transport |