You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2017/12/21 06:02:58 UTC
[trafficserver] branch quic-latest updated: Update loss detection
logic to draft-08
This is an automated email from the ASF dual-hosted git repository.
maskit pushed a commit to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/quic-latest by this push:
new ad7d9eb Update loss detection logic to draft-08
ad7d9eb is described below
commit ad7d9eb2859974acb1d3add8c7a6fc3816a42c17
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Thu Dec 21 15:02:15 2017 +0900
Update loss detection logic to draft-08
---
iocore/net/quic/QUICCongestionController.cc | 9 +-
iocore/net/quic/QUICCongestionController.h | 5 +-
iocore/net/quic/QUICLossDetector.cc | 337 ++++++++++++++++------------
iocore/net/quic/QUICLossDetector.h | 27 +--
4 files changed, 212 insertions(+), 166 deletions(-)
diff --git a/iocore/net/quic/QUICCongestionController.cc b/iocore/net/quic/QUICCongestionController.cc
index 96c2b55..3ce8e76 100644
--- a/iocore/net/quic/QUICCongestionController.cc
+++ b/iocore/net/quic/QUICCongestionController.cc
@@ -51,12 +51,12 @@ QUICCongestionController::handle_frame(std::shared_ptr<const QUICFrame> frame)
}
void
-QUICCongestionController::on_packet_sent()
+QUICCongestionController::on_packet_sent(size_t sent_bytes)
{
}
void
-QUICCongestionController::on_packet_acked()
+QUICCongestionController::on_packet_acked(QUICPacketNumber acked_packet_number)
{
}
@@ -66,6 +66,11 @@ QUICCongestionController::on_packets_lost(std::set<QUICPacketNumber> packets)
}
void
+QUICCongestionController::on_retransmission_timeout_verified()
+{
+}
+
+void
QUICCongestionController::on_rto_verified()
{
}
diff --git a/iocore/net/quic/QUICCongestionController.h b/iocore/net/quic/QUICCongestionController.h
index 1f76343..79cb96a 100644
--- a/iocore/net/quic/QUICCongestionController.h
+++ b/iocore/net/quic/QUICCongestionController.h
@@ -35,10 +35,11 @@ public:
virtual std::vector<QUICFrameType> interests() override;
virtual QUICErrorUPtr handle_frame(std::shared_ptr<const QUICFrame>) override;
- void on_packet_sent();
- void on_packet_acked();
+ void on_packet_sent(size_t sent_bytes);
+ void on_packet_acked(QUICPacketNumber acked_packet_number);
virtual void on_packets_lost(std::set<QUICPacketNumber> packets);
void on_rto_verified();
+ void on_retransmission_timeout_verified();
private:
};
diff --git a/iocore/net/quic/QUICLossDetector.cc b/iocore/net/quic/QUICLossDetector.cc
index f162221..7edd181 100644
--- a/iocore/net/quic/QUICLossDetector.cc
+++ b/iocore/net/quic/QUICLossDetector.cc
@@ -28,6 +28,17 @@
#define QUICLDDebug(fmt, ...) \
Debug("quic_loss_detector", "[%" PRIx64 "] " fmt, static_cast<uint64_t>(this->_connection_id), ##__VA_ARGS__)
+// 3.4.1. Constants of interest (draft-08)
+// Keep the order as the same as the spec so that we can see the difference easily.
+constexpr static uint32_t MAX_TLPS = 2;
+constexpr static uint32_t REORDERING_THRESHOLD = 3;
+constexpr static double TIME_REORDERING_FRACTION = 1 / 8;
+constexpr static ink_hrtime MIN_TLP_TIMEOUT = HRTIME_MSECONDS(10);
+constexpr static ink_hrtime MIN_RTO_TIMEOUT = HRTIME_MSECONDS(200);
+// This is defined on the spec but not used
+// constexpr static ink_hrtime DELAYED_ACK_TIMEOUT = HRTIME_MSECONDS(25);
+constexpr static ink_hrtime DEFAULT_INITIAL_RTT = HRTIME_MSECONDS(100);
+
QUICLossDetector::QUICLossDetector(QUICPacketTransmitter *transmitter, QUICCongestionController *cc)
: _transmitter(transmitter), _cc(cc)
{
@@ -35,9 +46,9 @@ QUICLossDetector::QUICLossDetector(QUICPacketTransmitter *transmitter, QUICConge
if (this->_time_loss_detection) {
this->_reordering_threshold = UINT32_MAX;
- this->_time_reordering_fraction = this->_TIME_REORDERING_FRACTION;
+ this->_time_reordering_fraction = TIME_REORDERING_FRACTION;
} else {
- this->_reordering_threshold = this->_REORDERING_THRESHOLD;
+ this->_reordering_threshold = REORDERING_THRESHOLD;
this->_time_reordering_fraction = INFINITY;
}
@@ -103,46 +114,6 @@ QUICLossDetector::largest_acked_packet_number()
}
void
-QUICLossDetector::_detect_lost_packets(QUICPacketNumber largest_acked_packet_number)
-{
- SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
- this->_loss_time = 0;
- std::set<QUICPacketNumber> lost_packets;
- uint32_t delay_until_lost = UINT32_MAX;
-
- if (this->_time_reordering_fraction != INFINITY) {
- delay_until_lost = (1 + this->_time_reordering_fraction) * std::max(this->_latest_rtt, this->_smoothed_rtt);
- } else if (largest_acked_packet_number == this->_largest_sent_packet) {
- // Early retransmit alarm.
- delay_until_lost = 9 / 8 * std::max(this->_latest_rtt, this->_smoothed_rtt);
- }
- for (auto &unacked : this->_sent_packets) {
- if (unacked.first >= largest_acked_packet_number) {
- break;
- }
- ink_hrtime time_since_sent = Thread::get_hrtime() - unacked.second->time;
- uint64_t packet_delta = largest_acked_packet_number - unacked.second->packet_number;
- if (time_since_sent > delay_until_lost) {
- lost_packets.insert(unacked.first);
- } else if (packet_delta > this->_reordering_threshold) {
- lost_packets.insert(unacked.first);
- } else if (this->_loss_time == 0 && delay_until_lost != INFINITY) {
- this->_loss_time = Thread::get_hrtime() + delay_until_lost - time_since_sent;
- }
- }
-
- // Inform the congestion controller of lost packets and
- // lets it decide whether to retransmit immediately.
- if (!lost_packets.empty()) {
- this->_cc->on_packets_lost(lost_packets);
- for (auto packet_number : lost_packets) {
- this->_decrement_packet_count(packet_number);
- this->_sent_packets.erase(packet_number);
- }
- }
-}
-
-void
QUICLossDetector::on_packet_sent(QUICPacketUPtr packet)
{
if (this->_connection_id == 0) {
@@ -152,34 +123,30 @@ QUICLossDetector::on_packet_sent(QUICPacketUPtr packet)
bool is_handshake = false;
QUICPacketType type = packet->type();
- // XXX: Should QUICPacketType::SERVER_STATELESS_RETRY be included?
if (type == QUICPacketType::INITIAL || type == QUICPacketType::HANDSHAKE) {
is_handshake = true;
}
QUICPacketNumber packet_number = packet->packet_number();
- bool is_retransmittable = packet->is_retransmittable();
+ bool is_ack_only = !packet->is_retransmittable();
size_t sent_bytes = packet->size();
- return this->_on_packet_sent(packet_number, is_retransmittable, is_handshake, sent_bytes, std::move(packet));
+ return this->_on_packet_sent(packet_number, is_ack_only, is_handshake, sent_bytes, std::move(packet));
}
void
-QUICLossDetector::_on_packet_sent(QUICPacketNumber packet_number, bool is_retransmittable, bool is_handshake, size_t sent_bytes,
+QUICLossDetector::_on_packet_sent(QUICPacketNumber packet_number, bool is_ack_only, bool is_handshake, size_t sent_bytes,
QUICPacketUPtr packet)
{
SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
- this->_largest_sent_packet = packet_number;
this->_time_of_last_sent_packet = Thread::get_hrtime();
+ this->_largest_sent_packet = packet_number;
// FIXME Should we really keep actual packet object?
- std::unique_ptr<PacketInfo> packet_info(new PacketInfo(
- {packet_number, this->_time_of_last_sent_packet, is_retransmittable, is_handshake, sent_bytes, std::move(packet)}));
- this->_sent_packets.insert(std::pair<QUICPacketNumber, std::unique_ptr<PacketInfo>>(packet_number, std::move(packet_info)));
- if (is_handshake) {
- ++this->_handshake_outstanding;
- }
- if (is_retransmittable) {
- ++this->_retransmittable_outstanding;
+ std::unique_ptr<PacketInfo> packet_info(
+ new PacketInfo({packet_number, this->_time_of_last_sent_packet, is_ack_only, is_handshake, sent_bytes, std::move(packet)}));
+ this->_add_to_sent_packet_list(packet_number, std::move(packet_info));
+ if (!is_ack_only) {
+ this->_cc->on_packet_sent(sent_bytes);
this->_set_loss_detection_alarm();
}
}
@@ -194,10 +161,7 @@ QUICLossDetector::_on_ack_received(const std::shared_ptr<const QUICAckFrame> &ac
if (pi != this->_sent_packets.end()) {
this->_latest_rtt = Thread::get_hrtime() - pi->second->time;
// _latest_rtt is nanosecond but ack_frame->ack_delay is millisecond
- if (this->_latest_rtt > static_cast<ink_hrtime>(HRTIME_MSECONDS(ack_frame->ack_delay()))) {
- this->_latest_rtt -= HRTIME_MSECONDS(ack_frame->ack_delay());
- }
- this->_update_rtt(this->_latest_rtt);
+ this->_update_rtt(this->_latest_rtt, HRTIME_MSECONDS(ack_frame->ack_delay()), ack_frame->largest_acknowledged());
}
QUICLDDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
@@ -220,69 +184,19 @@ QUICLossDetector::_on_ack_received(const std::shared_ptr<const QUICAckFrame> &ac
}
void
-QUICLossDetector::_on_packet_acked(QUICPacketNumber acked_packet_number)
+QUICLossDetector::_update_rtt(ink_hrtime latest_rtt, ink_hrtime ack_delay, QUICPacketNumber largest_acked)
{
- SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
- QUICLDDebug("Packet number %" PRIu64 " has been acked", acked_packet_number);
- // If a packet sent prior to RTO was acked, then the RTO
- // was spurious. Otherwise, inform congestion control.
- if (this->_rto_count > 0 && acked_packet_number > this->_largest_sent_before_rto) {
- // TODO cc->on_retransmission_timeout_verified();
- }
- this->_handshake_count = 0;
- this->_tlp_count = 0;
- this->_rto_count = 0;
- this->_decrement_packet_count(acked_packet_number);
- this->_sent_packets.erase(acked_packet_number);
-}
-
-void
-QUICLossDetector::_decrement_packet_count(QUICPacketNumber packet_number)
-{
- SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
- auto ite = this->_sent_packets.find(packet_number);
- if (ite != this->_sent_packets.end()) {
- if (ite->second->handshake) {
- --this->_handshake_outstanding;
- }
- if (ite->second->retransmittable) {
- --this->_retransmittable_outstanding;
+ // min_rtt ignores ack delay.
+ this->_min_rtt = std::min(this->_min_rtt, latest_rtt);
+ // Adjust for ack delay if it's plausible.
+ if (latest_rtt - this->_min_rtt > ack_delay) {
+ latest_rtt -= ack_delay;
+ // Only save into max ack delay if it's used for rtt calculation and is not ack only.
+ auto pi = this->_sent_packets.find(largest_acked);
+ if (pi != this->_sent_packets.end() && !pi->second->ack_only) {
+ this->_max_ack_delay = std::max(this->_max_ack_delay, ack_delay);
}
}
-}
-
-void
-QUICLossDetector::_on_loss_detection_alarm()
-{
- if (this->_handshake_outstanding) {
- // Handshake retransmission alarm.
- this->_retransmit_handshake_packets();
- this->_handshake_count++;
- } else if (this->_loss_time != 0) {
- // Early retransmit or Time Loss Detection
- this->_detect_lost_packets(this->_largest_acked_packet);
- } else if (this->_tlp_count < this->_MAX_TLPS) {
- // Tail Loss Probe.
- QUICLDDebug("TLP");
- this->_send_one_packet();
- this->_tlp_count++;
- } else {
- // RTO.
- if (this->_rto_count == 0) {
- this->_largest_sent_before_rto = this->_largest_sent_packet;
- }
- QUICLDDebug("RTO");
- this->_send_two_packets();
- this->_rto_count++;
- }
- QUICLDDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
- this->_retransmittable_outstanding.load(), this->_handshake_outstanding.load());
- this->_set_loss_detection_alarm();
-}
-
-void
-QUICLossDetector::_update_rtt(ink_hrtime latest_rtt)
-{
// Based on {{RFC6298}}.
if (this->_smoothed_rtt == 0) {
this->_smoothed_rtt = latest_rtt;
@@ -294,10 +208,29 @@ QUICLossDetector::_update_rtt(ink_hrtime latest_rtt)
}
void
+QUICLossDetector::_on_packet_acked(QUICPacketNumber acked_packet_number)
+{
+ SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+ QUICLDDebug("Packet number %" PRIu64 " has been acked", acked_packet_number);
+ this->_cc->on_packet_acked(acked_packet_number);
+ // If a packet sent prior to RTO was acked, then the RTO
+ // was spurious. Otherwise, inform congestion control.
+ if (this->_rto_count > 0 && acked_packet_number > this->_largest_sent_before_rto) {
+ this->_cc->on_retransmission_timeout_verified();
+ }
+ this->_handshake_count = 0;
+ this->_tlp_count = 0;
+ this->_rto_count = 0;
+ this->_remove_from_sent_packet_list(acked_packet_number);
+}
+
+void
QUICLossDetector::_set_loss_detection_alarm()
{
ink_hrtime alarm_duration;
- if (!this->_retransmittable_outstanding && this->_loss_detection_alarm) {
+ // Don't arm the alarm if there are no packets with
+ // retransmittable data in flight.
+ if (this->_retransmittable_outstanding == 0 && this->_loss_detection_alarm) {
this->_loss_detection_alarm_at = 0;
this->_loss_detection_alarm->cancel();
this->_loss_detection_alarm = nullptr;
@@ -307,30 +240,25 @@ QUICLossDetector::_set_loss_detection_alarm()
if (this->_handshake_outstanding) {
// Handshake retransmission alarm.
if (this->_smoothed_rtt == 0) {
- alarm_duration = 2 * this->_DEFAULT_INITIAL_RTT;
+ alarm_duration = 2 * DEFAULT_INITIAL_RTT;
} else {
alarm_duration = 2 * this->_smoothed_rtt;
}
- alarm_duration = std::max(alarm_duration, this->_MIN_TLP_TIMEOUT);
+ alarm_duration = std::max(alarm_duration, MIN_TLP_TIMEOUT);
alarm_duration = alarm_duration * (1 << this->_handshake_count);
QUICLDDebug("Handshake retransmission alarm will be set");
} else if (this->_loss_time != 0) {
// Early retransmit timer or time loss detection.
- alarm_duration = this->_loss_time - Thread::get_hrtime();
+ alarm_duration = this->_loss_time - this->_time_of_last_sent_packet;
QUICLDDebug("Early retransmit timer or time loss detection will be set");
- } else if (this->_tlp_count < this->_MAX_TLPS) {
+ } else if (this->_tlp_count < MAX_TLPS) {
// Tail Loss Probe
- if (this->_retransmittable_outstanding) {
- alarm_duration = 1.5 * this->_smoothed_rtt + this->_DELAYED_ACK_TIMEOUT;
- } else {
- alarm_duration = this->_MIN_TLP_TIMEOUT;
- }
- alarm_duration = std::max(alarm_duration, 2 * this->_smoothed_rtt);
+ alarm_duration = std::max(static_cast<ink_hrtime>(1.5 * this->_smoothed_rtt + this->_max_ack_delay), MIN_TLP_TIMEOUT);
QUICLDDebug("TLP alarm will be set");
} else {
// RTO alarm
alarm_duration = this->_smoothed_rtt + 4 * this->_rttvar;
- alarm_duration = std::max(alarm_duration, this->_MIN_RTO_TIMEOUT);
+ alarm_duration = std::max(alarm_duration, MIN_RTO_TIMEOUT);
alarm_duration = alarm_duration * (1 << this->_rto_count);
QUICLDDebug("RTO alarm will be set");
}
@@ -338,7 +266,7 @@ QUICLossDetector::_set_loss_detection_alarm()
if (this->_loss_detection_alarm_at) {
this->_loss_detection_alarm_at = std::min(this->_loss_detection_alarm_at, Thread::get_hrtime() + alarm_duration);
} else {
- this->_loss_detection_alarm_at = Thread::get_hrtime() + alarm_duration;
+ this->_loss_detection_alarm_at = this->_time_of_last_sent_packet + alarm_duration;
}
QUICLDDebug("Loss detection alarm has been set to %" PRId64, alarm_duration);
@@ -347,26 +275,77 @@ QUICLossDetector::_set_loss_detection_alarm()
}
}
-std::set<QUICPacketNumber>
-QUICLossDetector::_determine_newly_acked_packets(const QUICAckFrame &ack_frame)
+void
+QUICLossDetector::_on_loss_detection_alarm()
{
- std::set<QUICPacketNumber> packets;
- QUICPacketNumber x = ack_frame.largest_acknowledged();
- for (uint64_t i = 0; i <= ack_frame.ack_block_section()->first_ack_block_length(); ++i) {
- packets.insert(x--);
+ if (this->_handshake_outstanding) {
+ // Handshake retransmission alarm.
+ this->_retransmit_handshake_packets();
+ this->_handshake_count++;
+ } else if (this->_loss_time != 0) {
+ // Early retransmit or Time Loss Detection
+ this->_detect_lost_packets(this->_largest_acked_packet);
+ } else if (this->_tlp_count < MAX_TLPS) {
+ // Tail Loss Probe.
+ QUICLDDebug("TLP");
+ this->_send_one_packet();
+ this->_tlp_count++;
+ } else {
+ // RTO.
+ if (this->_rto_count == 0) {
+ this->_largest_sent_before_rto = this->_largest_sent_packet;
+ }
+ QUICLDDebug("RTO");
+ this->_send_two_packets();
+ this->_rto_count++;
}
- for (auto &&block : *(ack_frame.ack_block_section())) {
- for (uint64_t i = 0; i <= block.gap(); ++i) {
- x--;
+ QUICLDDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
+ this->_retransmittable_outstanding.load(), this->_handshake_outstanding.load());
+ this->_set_loss_detection_alarm();
+}
+
+void
+QUICLossDetector::_detect_lost_packets(QUICPacketNumber largest_acked_packet_number)
+{
+ SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+ this->_loss_time = 0;
+ std::set<QUICPacketNumber> lost_packets;
+ double delay_until_lost = INFINITY;
+
+ if (this->_time_loss_detection) {
+ delay_until_lost = (1 + this->_time_reordering_fraction) * std::max(this->_latest_rtt, this->_smoothed_rtt);
+ } else if (largest_acked_packet_number == this->_largest_sent_packet) {
+ // Early retransmit alarm.
+ delay_until_lost = 5 / 4 * std::max(this->_latest_rtt, this->_smoothed_rtt);
+ }
+
+ for (auto &unacked : this->_sent_packets) {
+ if (unacked.first >= largest_acked_packet_number) {
+ break;
}
- for (uint64_t i = 0; i <= block.length(); ++i) {
- packets.insert(x--);
+ ink_hrtime time_since_sent = Thread::get_hrtime() - unacked.second->time;
+ uint64_t packet_delta = largest_acked_packet_number - unacked.second->packet_number;
+ if (time_since_sent > delay_until_lost) {
+ lost_packets.insert(unacked.first);
+ } else if (packet_delta > this->_reordering_threshold) {
+ lost_packets.insert(unacked.first);
+ } else if (this->_loss_time == 0 && delay_until_lost != INFINITY) {
+ this->_loss_time = Thread::get_hrtime() + delay_until_lost - time_since_sent;
}
}
- return packets;
+ // Inform the congestion controller of lost packets and
+ // lets it decide whether to retransmit immediately.
+ if (!lost_packets.empty()) {
+ this->_cc->on_packets_lost(lost_packets);
+ for (auto packet_number : lost_packets) {
+ this->_remove_from_sent_packet_list(packet_number);
+ }
+ }
}
+// ===== Functions below are used on the spec but there're no pseudo code =====
+
void
QUICLossDetector::_retransmit_handshake_packets()
{
@@ -383,9 +362,7 @@ QUICLossDetector::_retransmit_handshake_packets()
}
for (auto packet_number : retransmitted_handshake_packets) {
- this->_sent_packets.erase(packet_number);
- --this->_handshake_outstanding;
- --this->_retransmittable_outstanding;
+ this->_remove_from_sent_packet_list(packet_number);
}
}
@@ -418,3 +395,69 @@ QUICLossDetector::_send_two_packets()
this->_transmitter->transmit_packet();
}
}
+
+// ===== Functions below are helper functions =====
+
+std::set<QUICPacketNumber>
+QUICLossDetector::_determine_newly_acked_packets(const QUICAckFrame &ack_frame)
+{
+ std::set<QUICPacketNumber> packets;
+ QUICPacketNumber x = ack_frame.largest_acknowledged();
+ for (uint64_t i = 0; i <= ack_frame.ack_block_section()->first_ack_block_length(); ++i) {
+ packets.insert(x--);
+ }
+ for (auto &&block : *(ack_frame.ack_block_section())) {
+ for (uint64_t i = 0; i <= block.gap(); ++i) {
+ x--;
+ }
+ for (uint64_t i = 0; i <= block.length(); ++i) {
+ packets.insert(x--);
+ }
+ }
+
+ return packets;
+}
+
+void
+QUICLossDetector::_add_to_sent_packet_list(QUICPacketNumber packet_number, std::unique_ptr<PacketInfo> packet_info)
+{
+ SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+
+ // Add to the list
+ this->_sent_packets.insert(std::pair<QUICPacketNumber, std::unique_ptr<PacketInfo>>(packet_number, std::move(packet_info)));
+
+ // Increment counters
+ auto ite = this->_sent_packets.find(packet_number);
+ if (ite != this->_sent_packets.end()) {
+ if (ite->second->handshake) {
+ ++this->_handshake_outstanding;
+ ink_assert(this->_handshake_outstanding.load() > 0);
+ }
+ if (!ite->second->ack_only) {
+ ++this->_retransmittable_outstanding;
+ ink_assert(this->_retransmittable_outstanding.load() > 0);
+ }
+ }
+}
+
+void
+QUICLossDetector::_remove_from_sent_packet_list(QUICPacketNumber packet_number)
+{
+ SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread());
+
+ // Decrement counters
+ auto ite = this->_sent_packets.find(packet_number);
+ if (ite != this->_sent_packets.end()) {
+ if (ite->second->handshake) {
+ ink_assert(this->_handshake_outstanding.load() > 0);
+ --this->_handshake_outstanding;
+ }
+ if (!ite->second->ack_only) {
+ ink_assert(this->_retransmittable_outstanding.load() > 0);
+ --this->_retransmittable_outstanding;
+ }
+ }
+
+ // Remove from the list
+ this->_sent_packets.erase(packet_number);
+}
diff --git a/iocore/net/quic/QUICLossDetector.h b/iocore/net/quic/QUICLossDetector.h
index ce2c629..e67598b 100644
--- a/iocore/net/quic/QUICLossDetector.h
+++ b/iocore/net/quic/QUICLossDetector.h
@@ -57,7 +57,7 @@ private:
struct PacketInfo {
QUICPacketNumber packet_number;
ink_hrtime time;
- bool retransmittable;
+ bool ack_only;
bool handshake;
size_t bytes;
QUICPacketUPtr packet;
@@ -67,35 +67,32 @@ private:
// TODO QUICCongestionController *cc = nullptr;
- // 3.2.1. Constants of interest
- uint32_t _MAX_TLPS = 2;
- uint32_t _REORDERING_THRESHOLD = 3;
- double _TIME_REORDERING_FRACTION = 1 / 8;
- ink_hrtime _MIN_TLP_TIMEOUT = HRTIME_MSECONDS(10);
- ink_hrtime _MIN_RTO_TIMEOUT = HRTIME_MSECONDS(200);
- ink_hrtime _DELAYED_ACK_TIMEOUT = HRTIME_MSECONDS(25);
- ink_hrtime _DEFAULT_INITIAL_RTT = HRTIME_MSECONDS(100);
-
- // 3.2.2. Variables of interest
+ // 3.4.2. Variables of interest (draft-08)
+ // Keep the order as the same as the spec so that we can see the difference easily.
Action *_loss_detection_alarm = nullptr;
uint32_t _handshake_count = 0;
uint32_t _tlp_count = 0;
uint32_t _rto_count = 0;
uint32_t _largest_sent_before_rto = 0;
+ ink_hrtime _time_of_last_sent_packet = 0;
uint32_t _largest_sent_packet = 0;
uint32_t _largest_acked_packet = 0;
- ink_hrtime _time_of_last_sent_packet = 0;
ink_hrtime _latest_rtt = 0;
ink_hrtime _smoothed_rtt = 0;
ink_hrtime _rttvar = 0;
+ ink_hrtime _min_rtt = 0;
+ ink_hrtime _max_ack_delay = 0;
uint32_t _reordering_threshold;
double _time_reordering_fraction;
ink_hrtime _loss_time = 0;
std::map<QUICPacketNumber, std::unique_ptr<PacketInfo>> _sent_packets;
+ // These are not defined on the spec but expected to be count
+ // These counter have to be updated when inserting / erasing packets from _sent_packets with following functions.
std::atomic<uint32_t> _handshake_outstanding;
std::atomic<uint32_t> _retransmittable_outstanding;
- void _decrement_packet_count(QUICPacketNumber packet_number);
+ void _add_to_sent_packet_list(QUICPacketNumber packet_number, std::unique_ptr<PacketInfo> packet_info);
+ void _remove_from_sent_packet_list(QUICPacketNumber packet_number);
/*
* Because this alarm will be reset on every packet transmission, to reduce number of events,
@@ -103,11 +100,11 @@ private:
*/
ink_hrtime _loss_detection_alarm_at = 0;
- void _on_packet_sent(QUICPacketNumber packet_number, bool is_retransmittable, bool is_handshake, size_t sent_bytes,
+ void _on_packet_sent(QUICPacketNumber packet_number, bool is_ack_only, bool is_handshake, size_t sent_bytes,
QUICPacketUPtr packet);
void _on_ack_received(const std::shared_ptr<const QUICAckFrame> &ack_frame);
void _on_packet_acked(QUICPacketNumber acked_packet_number);
- void _update_rtt(ink_hrtime latest_rtt);
+ void _update_rtt(ink_hrtime latest_rtt, ink_hrtime ack_delay, QUICPacketNumber largest_acked);
void _detect_lost_packets(QUICPacketNumber largest_acked);
void _set_loss_detection_alarm();
void _on_loss_detection_alarm();
--
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].