summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlberto Compagno <acompagn+fdio@cisco.com>2019-10-18 12:12:14 +0000
committerGerrit Code Review <gerrit@fd.io>2019-10-18 12:12:14 +0000
commit306b098c350771c9497219694f82c090634eb974 (patch)
tree7ed3fde6d7a60fa265d5c00abd18cdbf9263526e
parente829c967195260afe705d2b937fa2df5ce403699 (diff)
parent8dfba586faa8ebee05d9aa48217c484e6f2d0bf6 (diff)
Merge "[HICN-337] correlty set timers for rtx in rtc consumer"
-rw-r--r--libtransport/src/hicn/transport/protocols/rtc.cc75
-rw-r--r--libtransport/src/hicn/transport/protocols/rtc.h3
2 files changed, 54 insertions, 24 deletions
diff --git a/libtransport/src/hicn/transport/protocols/rtc.cc b/libtransport/src/hicn/transport/protocols/rtc.cc
index db36473cb..620523cbe 100644
--- a/libtransport/src/hicn/transport/protocols/rtc.cc
+++ b/libtransport/src/hicn/transport/protocols/rtc.cc
@@ -87,6 +87,9 @@ void RTCTransportProtocol::reset() {
interestRetransmissions_.clear();
lastSegNacked_ = 0;
lastReceived_ = 0;
+ lastReceivedTime_ = std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
highestReceived_ = 0;
firstSequenceInRound_ = 0;
@@ -205,7 +208,7 @@ void RTCTransportProtocol::updateStats(uint32_t round_duration) {
((1 - HICN_ESTIMATED_BW_ALPHA) * bytesPerSec);
}
- uint64_t minRtt = 150;
+ uint64_t minRtt = UINT_MAX;
uint64_t maxRtt = 0;
for (auto it = pathTable_.begin(); it != pathTable_.end(); it++) {
@@ -228,7 +231,7 @@ void RTCTransportProtocol::updateStats(uint32_t round_duration) {
//as a queuing delay we keep the lowest one among the two paths
//if one path is congested the forwarder should decide to do not
- //use it soon so it does not make sens to inform the application
+ //use it so it does not make sense to inform the application
//that maybe we have a problem
if(pathTable_[producerPathLabels_[0]]->getQueuingDealy() <
pathTable_[producerPathLabels_[1]]->getQueuingDealy())
@@ -506,6 +509,7 @@ void RTCTransportProtocol::addRetransmissions(uint32_t start, uint32_t stop) {
std::chrono::steady_clock::now().time_since_epoch())
.count();
+ bool new_rtx = false;
for (uint32_t i = start; i < stop; i++) {
auto it = interestRetransmissions_.find(i);
if (it == interestRetransmissions_.end()) {
@@ -519,13 +523,21 @@ void RTCTransportProtocol::addRetransmissions(uint32_t start, uint32_t stop) {
//we reset the transmission time setting to now, so that rtx will
//happne in one RTT on waint one inter arrival gap
inflightInterests_[pkt].transmissionTime = now;
+ new_rtx = true;
}
} // if the retransmission is already there the rtx timer will
// take care of it
}
- if(!rtx_timer_used_)
+ //in case a new rtx is added to the map we need to run checkRtx()
+ if(new_rtx){
+ if(rtx_timer_used_){
+ //if a timer is pending we need to delete it
+ rtx_timer_->cancel();
+ rtx_timer_used_ = false;
+ }
checkRtx();
+ }
}
uint64_t RTCTransportProtocol::retransmit() {
@@ -540,6 +552,9 @@ uint64_t RTCTransportProtocol::retransmit() {
it = interestRetransmissions_.begin();
uint64_t smallest_timeout = ULONG_MAX;
+ uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
while (it != interestRetransmissions_.end()) {
uint32_t pkt = it->first & modMask_;
@@ -563,31 +578,38 @@ uint64_t RTCTransportProtocol::retransmit() {
continue;
}
-
- uint64_t sent_time = inflightInterests_[pkt].transmissionTime;
- uint64_t rtx_time = sent_time;
-
- if(it->second == 0 &&
- pathTable_.find(producerPathLabels_[0]) != pathTable_.end() &&
- (pathTable_[producerPathLabels_[0]]->getInterArrivalGap() <
- pathTable_[producerPathLabels_[0]]->getMinRtt())){
- if(pathTable_.find(producerPathLabels_[1]) != pathTable_.end()){
- //first rtx: wait RTTmax - RTTmin + gap
- rtx_time = sent_time + pathTable_[producerPathLabels_[1]]->getMinRtt() -
- pathTable_[producerPathLabels_[0]]->getMinRtt() +
- pathTable_[producerPathLabels_[0]]->getInterArrivalGap();
+ uint64_t rtx_time = now;
+
+ if(it->second == 0) {
+ //first rtx
+ if(producerPathLabels_[0] != producerPathLabels_[1]){
+ //multipath
+ if(pathTable_.find(producerPathLabels_[0]) != pathTable_.end() &&
+ pathTable_.find(producerPathLabels_[1]) != pathTable_.end() &&
+ (pathTable_[producerPathLabels_[0]]->getInterArrivalGap() <
+ HICN_MIN_INTER_ARRIVAL_GAP)){
+ rtx_time = lastReceivedTime_ +
+ (pathTable_[producerPathLabels_[1]]->getMinRtt() -
+ pathTable_[producerPathLabels_[0]]->getMinRtt()) +
+ pathTable_[producerPathLabels_[0]]->getInterArrivalGap();
+ }//else low rate producer, send it immediatly
+ }else{
+ //single path
+ if(pathTable_.find(producerPathLabels_[0]) != pathTable_.end() &&
+ (pathTable_[producerPathLabels_[0]]->getInterArrivalGap() <
+ HICN_MIN_INTER_ARRIVAL_GAP)){
+ rtx_time = lastReceivedTime_ +
+ pathTable_[producerPathLabels_[0]]->getInterArrivalGap();
+ }//else low rate producer send immediatly
}
}else{
+ //second or plus rtx, wait for the min rtt
if(pathTable_.find(producerPathLabels_[0]) != pathTable_.end()){
- //second+ rtx: wait min rtt
+ uint64_t sent_time = inflightInterests_[pkt].transmissionTime;
rtx_time = sent_time + pathTable_[producerPathLabels_[0]]->getMinRtt();
- }
+ }//if we don't have info we send it immediatly
}
- uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
- std::chrono::steady_clock::now().time_since_epoch())
- .count();
-
if(now >= rtx_time){
inflightInterests_[pkt].transmissionTime = now;
it->second++;
@@ -612,7 +634,6 @@ void RTCTransportProtocol::checkRtx() {
return;
}
- rtx_timer_used_ = true;
uint64_t next_timeout = retransmit();
uint64_t wait = 1;
uint64_t now = std::chrono::duration_cast<std::chrono::milliseconds>(
@@ -621,9 +642,11 @@ void RTCTransportProtocol::checkRtx() {
if(next_timeout != ULONG_MAX && now < next_timeout){
wait = next_timeout - now;
}
+ rtx_timer_used_ = true;
rtx_timer_->expires_from_now(std::chrono::milliseconds(wait));
rtx_timer_->async_wait([this](std::error_code ec) {
if (ec) return;
+ rtx_timer_used_ = false;
checkRtx();
});
}
@@ -822,7 +845,11 @@ void RTCTransportProtocol::onContentObject(
highestReceived_ = segmentNumber;
}
if(segmentNumber > lastReceived_){
- lastReceived_ = segmentNumber;
+ lastReceived_ = segmentNumber;
+ lastReceivedTime_ = std::chrono::duration_cast<
+ std::chrono::milliseconds>(
+ std::chrono::steady_clock::now().time_since_epoch())
+ .count();
}
receivedData_++;
inflightInterests_[pkt].state = received_;
diff --git a/libtransport/src/hicn/transport/protocols/rtc.h b/libtransport/src/hicn/transport/protocols/rtc.h
index cac885bc4..7927e3969 100644
--- a/libtransport/src/hicn/transport/protocols/rtc.h
+++ b/libtransport/src/hicn/transport/protocols/rtc.h
@@ -49,6 +49,7 @@
#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
@@ -159,6 +160,8 @@ class RTCTransportProtocol : public TransportProtocol, public Reassembly {
//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
//rtt probes
//the RTC transport tends to overestimate the RTT