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/06 00:49:25 UTC
[trafficserver] branch quic-latest updated: fix #2793 rework quic
ack creator
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 9576d28 fix #2793 rework quic ack creator
9576d28 is described below
commit 9576d280286361a61832eb0e9ff1a2e86947aebf
Author: scw00 <sc...@apache.org>
AuthorDate: Fri Nov 17 10:59:46 2017 +0800
fix #2793 rework quic ack creator
---
iocore/net/quic/QUICAckFrameCreator.cc | 110 ++++++++++++++++++-----
iocore/net/quic/QUICAckFrameCreator.h | 28 ++++--
iocore/net/quic/test/test_QUICAckFrameCreator.cc | 74 +++++++++++++++
3 files changed, 183 insertions(+), 29 deletions(-)
diff --git a/iocore/net/quic/QUICAckFrameCreator.cc b/iocore/net/quic/QUICAckFrameCreator.cc
index f352d83..89b9525 100644
--- a/iocore/net/quic/QUICAckFrameCreator.cc
+++ b/iocore/net/quic/QUICAckFrameCreator.cc
@@ -28,14 +28,11 @@
int
QUICAckFrameCreator::update(QUICPacketNumber packet_number, bool acknowledgable)
{
- if (this->_packet_count == MAXIMUM_PACKET_COUNT) {
+ if (this->_packet_numbers.size() == MAXIMUM_PACKET_COUNT) {
return -1;
}
- if (packet_number > this->_largest_ack_number) {
- this->_largest_ack_number = packet_number;
- this->_largest_ack_received_time = Thread::get_hrtime();
- }
- this->_packet_numbers[this->_packet_count++] = packet_number - this->_last_ack_number;
+
+ this->_packet_numbers.push_back(packet_number);
if (acknowledgable && !this->_can_send) {
this->_can_send = true;
}
@@ -48,10 +45,10 @@ QUICAckFrameCreator::create()
{
std::unique_ptr<QUICAckFrame, QUICFrameDeleterFunc> ack_frame = {nullptr, QUICFrameDeleter::delete_null_frame};
if (this->_can_send) {
- ack_frame = this->_create_ack_frame();
- this->_last_ack_number = this->_largest_ack_number;
- this->_can_send = false;
- this->_packet_count = 0;
+ ack_frame = this->_create_ack_frame();
+ this->_can_send = false;
+ this->_packet_count = 0;
+ this->_packet_numbers.clear();
}
return ack_frame;
}
@@ -67,37 +64,102 @@ void
QUICAckFrameCreator::_sort_packet_numbers()
{
// TODO Find more smart way
- std::sort(this->_packet_numbers, this->_packet_numbers + this->_packet_count);
}
std::unique_ptr<QUICAckFrame, QUICFrameDeleterFunc>
QUICAckFrameCreator::_create_ack_frame()
{
std::unique_ptr<QUICAckFrame, QUICFrameDeleterFunc> ack_frame = {nullptr, QUICFrameDeleter::delete_null_frame};
- this->_sort_packet_numbers();
- uint16_t start = this->_packet_numbers[0];
- uint8_t gap = 0;
- int i;
+ this->_packet_numbers.sort();
+ QUICPacketNumber largest_ack_number = this->_packet_numbers.largest_ack_number();
+ QUICPacketNumber last_ack_number = largest_ack_number;
+
+ size_t i = 0;
+ uint8_t gap = 0;
uint64_t length = 0;
- for (i = 0, length = 0; i < this->_packet_count; ++i, ++length) {
- if (this->_packet_numbers[i] == start + length) {
+
+ while (i < this->_packet_numbers.size()) {
+ if (this->_packet_numbers[i] == last_ack_number) {
+ last_ack_number--;
+ length++;
+ i++;
continue;
}
+
if (ack_frame) {
ack_frame->ack_block_section()->add_ack_block({gap, length});
} else {
- uint16_t delay = (Thread::get_hrtime() - this->_largest_ack_received_time) / 1000; // TODO Milliseconds?
- ack_frame = QUICFrameFactory::create_ack_frame(this->_largest_ack_number, delay, length);
+ uint16_t delay = (Thread::get_hrtime() - this->_packet_numbers.largest_ack_received_time()) / 1000; // TODO Milliseconds?
+ ack_frame = QUICFrameFactory::create_ack_frame(largest_ack_number, delay, length);
}
- gap = this->_packet_numbers[i] - this->_packet_numbers[i - 1] - 1;
- start = this->_packet_numbers[i];
- length = 0;
+
+ gap = last_ack_number - this->_packet_numbers[i];
+ last_ack_number = this->_packet_numbers[i];
+ length = 0;
}
+
if (ack_frame) {
ack_frame->ack_block_section()->add_ack_block({gap, length});
} else {
- uint16_t delay = (Thread::get_hrtime() - this->_largest_ack_received_time) / 1000; // TODO Milliseconds?
- ack_frame = QUICFrameFactory::create_ack_frame(this->_largest_ack_number, delay, length);
+ uint16_t delay = (Thread::get_hrtime() - this->_packet_numbers.largest_ack_received_time()) / 1000; // TODO Milliseconds?
+ ack_frame = QUICFrameFactory::create_ack_frame(largest_ack_number, delay, length);
}
return ack_frame;
}
+
+void
+QUICAckPacketNumbers::push_back(QUICPacketNumber packet_number)
+{
+ if (packet_number > this->_largest_ack_number) {
+ this->_largest_ack_received_time = Thread::get_hrtime();
+ this->_largest_ack_number = packet_number;
+ }
+
+ this->_packet_numbers.push_back(packet_number);
+}
+
+QUICPacketNumber
+QUICAckPacketNumbers::front()
+{
+ return this->_packet_numbers.front();
+}
+
+QUICPacketNumber
+QUICAckPacketNumbers::back()
+{
+ return this->_packet_numbers.back();
+}
+
+size_t
+QUICAckPacketNumbers::size()
+{
+ return this->_packet_numbers.size();
+}
+
+void
+QUICAckPacketNumbers::clear()
+{
+ this->_packet_numbers.clear();
+ this->_largest_ack_number = 0;
+ this->_largest_ack_received_time = 0;
+}
+
+QUICPacketNumber
+QUICAckPacketNumbers::largest_ack_number()
+{
+ return this->_largest_ack_number;
+}
+
+ink_hrtime
+QUICAckPacketNumbers::largest_ack_received_time()
+{
+ return this->_largest_ack_received_time;
+}
+
+void
+QUICAckPacketNumbers::sort()
+{
+ // TODO Find more smart way
+ std::sort(this->_packet_numbers.begin(), this->_packet_numbers.end(),
+ [](QUICPacketNumber a, QUICPacketNumber b) -> bool { return b < a; });
+}
diff --git a/iocore/net/quic/QUICAckFrameCreator.h b/iocore/net/quic/QUICAckFrameCreator.h
index 7251747..da59c5e 100644
--- a/iocore/net/quic/QUICAckFrameCreator.h
+++ b/iocore/net/quic/QUICAckFrameCreator.h
@@ -27,6 +27,28 @@
#include "QUICTypes.h"
#include "QUICFrame.h"
+class QUICAckPacketNumbers
+{
+public:
+ void push_back(QUICPacketNumber packet_number);
+ QUICPacketNumber front();
+ QUICPacketNumber back();
+ size_t size();
+ void clear();
+ void sort();
+
+ QUICPacketNumber largest_ack_number();
+ ink_hrtime largest_ack_received_time();
+
+ const QUICPacketNumber &operator[](int i) const { return this->_packet_numbers[i]; }
+
+private:
+ QUICPacketNumber _largest_ack_number = 0;
+ ink_hrtime _largest_ack_received_time = 0;
+
+ std::vector<QUICPacketNumber> _packet_numbers;
+};
+
class QUICAckFrameCreator
{
public:
@@ -57,11 +79,7 @@ public:
private:
bool _can_send = false;
- QUICPacketNumber _largest_ack_number = 0;
- QUICPacketNumber _last_ack_number = 0;
- ink_hrtime _largest_ack_received_time = 0;
-
- uint16_t _packet_numbers[MAXIMUM_PACKET_COUNT];
+ QUICAckPacketNumbers _packet_numbers;
uint16_t _packet_count = 0;
void _sort_packet_numbers();
diff --git a/iocore/net/quic/test/test_QUICAckFrameCreator.cc b/iocore/net/quic/test/test_QUICAckFrameCreator.cc
index a519687..1ca0691 100644
--- a/iocore/net/quic/test/test_QUICAckFrameCreator.cc
+++ b/iocore/net/quic/test/test_QUICAckFrameCreator.cc
@@ -64,6 +64,80 @@ TEST_CASE("QUICAckFrameCreator", "[quic]")
CHECK(frame != nullptr);
CHECK(frame->num_blocks() == 1);
CHECK(frame->largest_acknowledged() == 10);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 1);
+ CHECK(frame->ack_block_section()->begin()->gap() == 2);
+}
+
+TEST_CASE("QUICAckFrameCreator_loss_recover", "[quic]")
+{
+ QUICAckFrameCreator creator;
+ std::unique_ptr<QUICAckFrame, QUICFrameDeleterFunc> frame = {nullptr, nullptr};
+
+ // Initial state
+ frame = creator.create();
+ CHECK(frame == nullptr);
+
+ creator.update(2, true);
+ creator.update(5, true);
+ creator.update(6, true);
+ creator.update(8, true);
+ creator.update(9, true);
+
+ frame = creator.create();
+ CHECK(frame != nullptr);
+ CHECK(frame->num_blocks() == 2);
+ CHECK(frame->largest_acknowledged() == 9);
CHECK(frame->ack_block_section()->first_ack_block_length() == 2);
+ CHECK(frame->ack_block_section()->begin()->gap() == 1);
+
+ frame = creator.create();
+ CHECK(frame == nullptr);
+
+ creator.update(7, true);
+ creator.update(4, true);
+ frame = creator.create();
+ CHECK(frame != nullptr);
+ CHECK(frame->num_blocks() == 1);
+ CHECK(frame->largest_acknowledged() == 7);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 1);
CHECK(frame->ack_block_section()->begin()->gap() == 2);
}
+
+TEST_CASE("QUICAckFrameCreator_QUICAckPacketNumbers", "[quic]")
+{
+ QUICAckPacketNumbers packet_numbers;
+
+ CHECK(packet_numbers.size() == 0);
+ CHECK(packet_numbers.largest_ack_number() == 0);
+ CHECK(packet_numbers.largest_ack_received_time() == 0);
+
+ Thread::get_hrtime_updated();
+
+ packet_numbers.push_back(3);
+ CHECK(packet_numbers.size() == 1);
+ CHECK(packet_numbers.largest_ack_number() == 3);
+
+ ink_hrtime ti = packet_numbers.largest_ack_received_time();
+ CHECK(packet_numbers.largest_ack_received_time() != 0);
+
+ Thread::get_hrtime_updated();
+
+ packet_numbers.push_back(2);
+ CHECK(packet_numbers.size() == 2);
+ CHECK(packet_numbers.largest_ack_number() == 3);
+ CHECK(packet_numbers.largest_ack_received_time() == ti);
+
+ Thread::get_hrtime_updated();
+
+ packet_numbers.push_back(10);
+ CHECK(packet_numbers.size() == 3);
+ CHECK(packet_numbers.largest_ack_number() == 10);
+ CHECK(packet_numbers.largest_ack_received_time() > ti);
+
+ Thread::get_hrtime_updated();
+
+ packet_numbers.clear();
+ CHECK(packet_numbers.size() == 0);
+ CHECK(packet_numbers.largest_ack_number() == 0);
+ CHECK(packet_numbers.largest_ack_received_time() == 0);
+}
--
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].