/* * 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 #include #include #include #include #include // 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.1 #define HICN_WIN_DECREASE_FACTOR 0.8 // 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 Reassembly { public: RTCTransportProtocol(interface::ConsumerSocket *icnet_socket); ~RTCTransportProtocol(); int start() override; void stop() override; void resume() 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 returnContentToApplication(const ContentObject &content_object); TRANSPORT_ALWAYS_INLINE virtual void reassemble( ContentObject::Ptr &&content_object) override { returnContentToApplication(*content_object); } // controller var std::unique_ptr 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 interestRetransmissions_; bool rtx_timer_used_; std::unique_ptr rtx_timer_; std::vector 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 sentinel_timer_; uint64_t lastEvent_; //time at which we removed a pending //interest from the window std::unordered_map 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 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> pathTable_; uint32_t roundCounter_; // CC var double estimatedBw_; double lossRate_; double queuingDelay_; unsigned protocolState_; bool initied; TransportStatistics stats_; }; } // namespace protocol } // namespace transport