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/13 23:44:37 UTC
[trafficserver] 05/08: Parse and create ack block in draft-08 way
This is an automated email from the ASF dual-hosted git repository.
masaori pushed a commit to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit af62ebda49bc8511b61209f59d3fb3f6f6364615
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Wed Dec 13 12:10:50 2017 +0900
Parse and create ack block in draft-08 way
---
iocore/net/P_QUICNetVConnection.h | 8 +-
iocore/net/QUICNetVConnection.cc | 10 +-
iocore/net/quic/Mock.h | 60 +++++----
iocore/net/quic/QUICAckFrameCreator.cc | 8 +-
iocore/net/quic/QUICCongestionController.cc | 20 +++
iocore/net/quic/QUICCongestionController.h | 9 +-
iocore/net/quic/QUICFrame.cc | 1 +
iocore/net/quic/QUICLossDetector.cc | 17 ++-
iocore/net/quic/QUICLossDetector.h | 4 +-
iocore/net/quic/QUICPacketTransmitter.h | 6 +-
iocore/net/quic/test/test_QUICAckFrameCreator.cc | 16 +--
iocore/net/quic/test/test_QUICLossDetector.cc | 150 ++++++++++++++++++-----
12 files changed, 229 insertions(+), 80 deletions(-)
diff --git a/iocore/net/P_QUICNetVConnection.h b/iocore/net/P_QUICNetVConnection.h
index 6d3a12a..4f4ba37 100644
--- a/iocore/net/P_QUICNetVConnection.h
+++ b/iocore/net/P_QUICNetVConnection.h
@@ -177,7 +177,7 @@ public:
QUICPacketNumber largest_acked_packet_number() override;
// QUICConnection (QUICPacketTransmitter)
- virtual void transmit_packet(QUICPacketUPtr packet) override;
+ virtual uint32_t transmit_packet(QUICPacketUPtr packet) override;
virtual void retransmit_packet(const QUICPacket &packet) override;
virtual Ptr<ProxyMutex> get_packet_transmitter_mutex() override;
@@ -229,8 +229,8 @@ private:
QUICRemoteFlowController *_remote_flow_controller = nullptr;
QUICLocalFlowController *_local_flow_controller = nullptr;
- Queue<UDPPacket> _packet_recv_queue;
- Queue<QUICPacket> _packet_send_queue;
+ CountQueue<UDPPacket> _packet_recv_queue;
+ CountQueue<QUICPacket> _packet_send_queue;
std::queue<QUICPacketUPtr> _quic_packet_recv_queue;
// `_frame_send_queue` is the queue for any type of frame except STREAM frame.
// The flow contorl doesn't blcok frames in this queue.
@@ -243,7 +243,7 @@ private:
void _close_packet_write_ready(Event *data);
Event *_packet_write_ready = nullptr;
- void _transmit_packet(QUICPacketUPtr);
+ uint32_t _transmit_packet(QUICPacketUPtr);
void _transmit_frame(QUICFrameUPtr);
void _store_frame(ats_unique_buf &buf, size_t &len, bool &retransmittable, QUICPacketType ¤t_packet_type,
diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc
index 013d1ee..228134c 100644
--- a/iocore/net/QUICNetVConnection.cc
+++ b/iocore/net/QUICNetVConnection.cc
@@ -110,7 +110,7 @@ QUICNetVConnection::start(SSL_CTX *ssl_ctx)
// Create frame handlers
this->_stream_manager = new QUICStreamManager(this->connection_id(), this, this->_application_map);
this->_congestion_controller = new QUICCongestionController();
- this->_loss_detector = new QUICLossDetector(this);
+ this->_loss_detector = new QUICLossDetector(this, this->_congestion_controller);
this->_remote_flow_controller = new QUICRemoteConnectionFlowController(0, this);
this->_local_flow_controller = new QUICLocalConnectionFlowController(0, this);
@@ -216,7 +216,7 @@ QUICNetVConnection::stream_manager()
return this->_stream_manager;
}
-void
+uint32_t
QUICNetVConnection::_transmit_packet(QUICPacketUPtr packet)
{
SCOPED_MUTEX_LOCK(packet_transmitter_lock, this->_packet_transmitter_mutex, this_ethread());
@@ -225,13 +225,15 @@ QUICNetVConnection::_transmit_packet(QUICPacketUPtr packet)
packet->size());
// TODO Remove const_cast
this->_packet_send_queue.enqueue(const_cast<QUICPacket *>(packet.release()));
+ return this->_packet_send_queue.size;
}
-void
+uint32_t
QUICNetVConnection::transmit_packet(QUICPacketUPtr packet)
{
- this->_transmit_packet(std::move(packet));
+ uint32_t npackets = this->_transmit_packet(std::move(packet));
this->_schedule_packet_write_ready();
+ return npackets;
}
void
diff --git a/iocore/net/quic/Mock.h b/iocore/net/quic/Mock.h
index 3050a43..363de99 100644
--- a/iocore/net/quic/Mock.h
+++ b/iocore/net/quic/Mock.h
@@ -157,10 +157,11 @@ public:
return 0;
}
- void
+ uint32_t
transmit_packet(QUICPacketUPtr packet) override
{
++_transmit_count;
+ return 1;
}
void
@@ -275,16 +276,21 @@ class MockQUICPacketTransmitter : public QUICPacketTransmitter
{
public:
MockQUICPacketTransmitter() : QUICPacketTransmitter() { this->_mutex = new_ProxyMutex(); };
- void
+
+ uint32_t
transmit_packet(QUICPacketUPtr packet) override
{
- ++_transmit_count;
+ if (packet) {
+ this->transmitted.insert(packet->packet_number());
+ return 1;
+ }
+ return 0;
}
void
retransmit_packet(const QUICPacket &packet) override
{
- ++_retransmit_count;
+ this->retransmitted.insert(packet.packet_number());
}
Ptr<ProxyMutex>
@@ -293,9 +299,10 @@ public:
return this->_mutex;
}
- int _transmit_count = 0;
- int _retransmit_count = 0;
Ptr<ProxyMutex> _mutex;
+
+ std::set<QUICPacketNumber> transmitted;
+ std::set<QUICPacketNumber> retransmitted;
};
class MockQUICFrameTransmitter : public QUICFrameTransmitter
@@ -316,25 +323,9 @@ public:
int frameCount[256] = {0};
};
-class MockQUICLossDetector : public QUICLossDetector
-{
-public:
- MockQUICLossDetector() : QUICLossDetector(new MockQUICPacketTransmitter()) {}
- void
- rcv_frame(std::shared_ptr<const QUICFrame>)
- {
- }
-
- void
- on_packet_sent(QUICPacketUPtr packet)
- {
- }
-};
-
class MockQUICCongestionController : public QUICCongestionController
{
public:
- MockQUICCongestionController() : QUICCongestionController() {}
// Override
virtual QUICErrorUPtr
handle_frame(std::shared_ptr<const QUICFrame> f) override
@@ -345,6 +336,14 @@ public:
return QUICErrorUPtr(new QUICNoError());
}
+ virtual void
+ on_packets_lost(std::set<QUICPacketNumber> packets) override
+ {
+ for (auto pn : packets) {
+ lost_packets.insert(pn);
+ }
+ }
+
// for Test
int
getStreamFrameCount()
@@ -370,11 +369,28 @@ public:
return _totalFrameCount;
}
+ std::set<QUICPacketNumber> lost_packets;
+
private:
int _totalFrameCount = 0;
int _frameCount[256] = {0};
};
+class MockQUICLossDetector : public QUICLossDetector
+{
+public:
+ MockQUICLossDetector() : QUICLossDetector(new MockQUICPacketTransmitter(), new MockQUICCongestionController()) {}
+ void
+ rcv_frame(std::shared_ptr<const QUICFrame>)
+ {
+ }
+
+ void
+ on_packet_sent(QUICPacketUPtr packet)
+ {
+ }
+};
+
class MockQUICApplication : public QUICApplication
{
public:
diff --git a/iocore/net/quic/QUICAckFrameCreator.cc b/iocore/net/quic/QUICAckFrameCreator.cc
index eb58c7f..8c1dafb 100644
--- a/iocore/net/quic/QUICAckFrameCreator.cc
+++ b/iocore/net/quic/QUICAckFrameCreator.cc
@@ -87,10 +87,10 @@ QUICAckFrameCreator::_create_ack_frame()
}
if (ack_frame) {
- ack_frame->ack_block_section()->add_ack_block({gap, length});
+ ack_frame->ack_block_section()->add_ack_block({static_cast<uint8_t>(gap - 1), length - 1});
} else {
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);
+ ack_frame = QUICFrameFactory::create_ack_frame(largest_ack_number, delay, length - 1);
}
gap = last_ack_number - this->_packet_numbers[i];
@@ -99,10 +99,10 @@ QUICAckFrameCreator::_create_ack_frame()
}
if (ack_frame) {
- ack_frame->ack_block_section()->add_ack_block({gap, length});
+ ack_frame->ack_block_section()->add_ack_block({static_cast<uint8_t>(gap - 1), length - 1});
} else {
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);
+ ack_frame = QUICFrameFactory::create_ack_frame(largest_ack_number, delay, length - 1);
}
return ack_frame;
}
diff --git a/iocore/net/quic/QUICCongestionController.cc b/iocore/net/quic/QUICCongestionController.cc
index d06902b..96c2b55 100644
--- a/iocore/net/quic/QUICCongestionController.cc
+++ b/iocore/net/quic/QUICCongestionController.cc
@@ -49,3 +49,23 @@ QUICCongestionController::handle_frame(std::shared_ptr<const QUICFrame> frame)
return error;
}
+
+void
+QUICCongestionController::on_packet_sent()
+{
+}
+
+void
+QUICCongestionController::on_packet_acked()
+{
+}
+
+void
+QUICCongestionController::on_packets_lost(std::set<QUICPacketNumber> packets)
+{
+}
+
+void
+QUICCongestionController::on_rto_verified()
+{
+}
diff --git a/iocore/net/quic/QUICCongestionController.h b/iocore/net/quic/QUICCongestionController.h
index d44b9bf..1f76343 100644
--- a/iocore/net/quic/QUICCongestionController.h
+++ b/iocore/net/quic/QUICCongestionController.h
@@ -23,7 +23,9 @@
#pragma once
-#include <QUICFrameHandler.h>
+#include <set>
+#include "QUICTypes.h"
+#include "QUICFrameHandler.h"
// TODO Implement congestion controll.
// Congestion controller will be required after the 2nd implementation draft.
@@ -33,5 +35,10 @@ 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();
+ virtual void on_packets_lost(std::set<QUICPacketNumber> packets);
+ void on_rto_verified();
+
private:
};
diff --git a/iocore/net/quic/QUICFrame.cc b/iocore/net/quic/QUICFrame.cc
index a91c78f..12b09f7 100644
--- a/iocore/net/quic/QUICFrame.cc
+++ b/iocore/net/quic/QUICFrame.cc
@@ -607,6 +607,7 @@ QUICAckFrame::AckBlockSection::const_iterator::const_iterator(uint8_t index, con
QUICAckFrame::AckBlockSection::const_iterator::const_iterator(uint8_t index, const std::vector<QUICAckFrame::AckBlock> *ack_block)
{
this->_index = index;
+ this->_buf = nullptr;
this->_ack_blocks = ack_block;
if (this->_ack_blocks->size()) {
if (this->_ack_blocks->size() == this->_index) {
diff --git a/iocore/net/quic/QUICLossDetector.cc b/iocore/net/quic/QUICLossDetector.cc
index 31cae5a..d735ae4 100644
--- a/iocore/net/quic/QUICLossDetector.cc
+++ b/iocore/net/quic/QUICLossDetector.cc
@@ -28,7 +28,8 @@
#define QUICLDDebug(fmt, ...) \
Debug("quic_loss_detector", "[%" PRIx64 "] " fmt, static_cast<uint64_t>(this->_connection_id), ##__VA_ARGS__)
-QUICLossDetector::QUICLossDetector(QUICPacketTransmitter *transmitter) : _transmitter(transmitter)
+QUICLossDetector::QUICLossDetector(QUICPacketTransmitter *transmitter, QUICCongestionController *cc)
+ : _transmitter(transmitter), _cc(cc)
{
this->mutex = new_ProxyMutex();
@@ -133,7 +134,7 @@ QUICLossDetector::_detect_lost_packets(QUICPacketNumber largest_acked_packet_num
// Inform the congestion controller of lost packets and
// lets it decide whether to retransmit immediately.
if (!lost_packets.empty()) {
- // TODO cc->on_packets_lost(lost_packets);
+ 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);
@@ -350,12 +351,16 @@ QUICLossDetector::_determine_newly_acked_packets(const QUICAckFrame &ack_frame)
{
std::set<QUICPacketNumber> packets;
QUICPacketNumber x = ack_frame.largest_acknowledged();
- packets.insert(x);
+ 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 (int i = 0; i < block.gap(); ++i) {
- packets.insert(++x);
+ for (uint64_t i = 0; i <= block.gap(); ++i) {
+ x--;
+ }
+ for (uint64_t i = 0; i <= block.length(); ++i) {
+ packets.insert(x--);
}
- x += block.length();
}
return packets;
diff --git a/iocore/net/quic/QUICLossDetector.h b/iocore/net/quic/QUICLossDetector.h
index b7071fc..d72785c 100644
--- a/iocore/net/quic/QUICLossDetector.h
+++ b/iocore/net/quic/QUICLossDetector.h
@@ -37,11 +37,12 @@
#include "QUICFrame.h"
#include "QUICFrameHandler.h"
#include "QUICPacketTransmitter.h"
+#include "QUICCongestionController.h"
class QUICLossDetector : public Continuation, public QUICFrameHandler
{
public:
- QUICLossDetector(QUICPacketTransmitter *transmitter);
+ QUICLossDetector(QUICPacketTransmitter *transmitter, QUICCongestionController *cc);
int event_handler(int event, Event *edata);
@@ -116,4 +117,5 @@ private:
void _retransmit_handshake_packets();
QUICPacketTransmitter *_transmitter = nullptr;
+ QUICCongestionController *_cc = nullptr;
};
diff --git a/iocore/net/quic/QUICPacketTransmitter.h b/iocore/net/quic/QUICPacketTransmitter.h
index 5396a6a..d562257 100644
--- a/iocore/net/quic/QUICPacketTransmitter.h
+++ b/iocore/net/quic/QUICPacketTransmitter.h
@@ -30,11 +30,13 @@ class QUICPacketTransmitter
{
public:
/*
- * Enqueue a packetfor transmission
+ * Enqueue a packet for transmission
*
+ * If packet parameter is not passed, it just sends an event without queuing a new packet.
* This sends QUIC_PACKET_WRITE_READY event.
+ * This return number of packets currently in queue
*/
- virtual void transmit_packet(QUICPacketUPtr packet) = 0;
+ virtual uint32_t transmit_packet(QUICPacketUPtr packet = QUICPacketUPtr(nullptr, &QUICPacketDeleter::delete_packet)) = 0;
/*
* Enqueue a packet for retransmission
diff --git a/iocore/net/quic/test/test_QUICAckFrameCreator.cc b/iocore/net/quic/test/test_QUICAckFrameCreator.cc
index 025d90c..09e742d 100644
--- a/iocore/net/quic/test/test_QUICAckFrameCreator.cc
+++ b/iocore/net/quic/test/test_QUICAckFrameCreator.cc
@@ -41,7 +41,7 @@ TEST_CASE("QUICAckFrameCreator", "[quic]")
CHECK(frame != nullptr);
CHECK(frame->num_blocks() == 0);
CHECK(frame->largest_acknowledged() == 1);
- CHECK(frame->ack_block_section()->first_ack_block_length() == 1);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 0);
frame = creator.create();
CHECK(frame == nullptr);
@@ -55,7 +55,7 @@ TEST_CASE("QUICAckFrameCreator", "[quic]")
CHECK(frame != nullptr);
CHECK(frame->num_blocks() == 0);
CHECK(frame->largest_acknowledged() == 5);
- CHECK(frame->ack_block_section()->first_ack_block_length() == 4);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 3);
// Loss
creator.update(6, true);
@@ -65,8 +65,8 @@ 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);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 0);
+ CHECK(frame->ack_block_section()->begin()->gap() == 1);
}
TEST_CASE("QUICAckFrameCreator_loss_recover", "[quic]")
@@ -88,8 +88,8 @@ TEST_CASE("QUICAckFrameCreator_loss_recover", "[quic]")
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);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 1);
+ CHECK(frame->ack_block_section()->begin()->gap() == 0);
frame = creator.create();
CHECK(frame == nullptr);
@@ -100,8 +100,8 @@ TEST_CASE("QUICAckFrameCreator_loss_recover", "[quic]")
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);
+ CHECK(frame->ack_block_section()->first_ack_block_length() == 0);
+ CHECK(frame->ack_block_section()->begin()->gap() == 1);
}
TEST_CASE("QUICAckFrameCreator_QUICAckPacketNumbers", "[quic]")
diff --git a/iocore/net/quic/test/test_QUICLossDetector.cc b/iocore/net/quic/test/test_QUICLossDetector.cc
index af39c41..17f6029 100644
--- a/iocore/net/quic/test/test_QUICLossDetector.cc
+++ b/iocore/net/quic/test/test_QUICLossDetector.cc
@@ -27,33 +27,127 @@
#include "QUICEvents.h"
#include "Mock.h"
-TEST_CASE("QUICLossDetector_Loss_in_Handshake", "[quic]")
+TEST_CASE("QUICLossDetector_Loss", "[quic]")
{
- MockQUICPacketTransmitter *tx = new MockQUICPacketTransmitter();
- QUICLossDetector detector(tx);
-
- // Check initial state
- CHECK(tx->_retransmit_count == 0);
-
- // Send SERVER_CLEARTEXT (Handshake message)
- uint8_t raw[4] = {0};
- ats_unique_buf payload = ats_unique_malloc(sizeof(raw));
- memcpy(payload.get(), raw, sizeof(raw));
-
- QUICPacketHeader *header = QUICPacketHeader::build(QUICPacketType::HANDSHAKE, 0xffddbb9977553311ULL, 0x00000001, 0, 0x00112233,
- std::move(payload), sizeof(raw));
- QUICPacketUPtr packet =
- QUICPacketUPtr(new QUICPacket(header, std::move(payload), sizeof(raw), true), [](QUICPacket *p) { delete p; });
- detector.on_packet_sent(std::move(packet));
- ink_hrtime_sleep(HRTIME_MSECONDS(1000));
- CHECK(tx->_retransmit_count > 0);
-
- // Receive ACK
- std::shared_ptr<QUICAckFrame> frame = std::make_shared<QUICAckFrame>(0x01, 20, 0);
- frame->ack_block_section()->add_ack_block({0, 1ULL});
- detector.handle_frame(frame);
- ink_hrtime_sleep(HRTIME_MSECONDS(1500));
- int retransmit_count = tx->_retransmit_count;
- ink_hrtime_sleep(HRTIME_MSECONDS(1500));
- CHECK(tx->_retransmit_count == retransmit_count);
+ MockQUICCrypto crypto;
+ QUICPacketFactory pf;
+ pf.set_crypto_module(&crypto);
+
+ QUICAckFrameCreator *afc = new QUICAckFrameCreator();
+ QUICConnectionId connection_id = 1;
+ MockQUICPacketTransmitter *tx = new MockQUICPacketTransmitter();
+ MockQUICCongestionController *cc = new MockQUICCongestionController();
+ QUICLossDetector detector(tx, cc);
+ ats_unique_buf payload = ats_unique_malloc(16);
+ size_t payload_len = 16;
+ QUICPacketUPtr packet = QUICPacketFactory::create_null_packet();
+ std::shared_ptr<QUICAckFrame> frame = QUICFrameFactory::create_null_ack_frame();
+ uint16_t ack_delay = 50;
+
+ SECTION("Handshake")
+ {
+ // Check initial state
+ CHECK(tx->retransmitted.size() == 0);
+
+ // Send SERVER_CLEARTEXT (Handshake message)
+ uint8_t raw[4] = {0};
+ ats_unique_buf payload = ats_unique_malloc(sizeof(raw));
+ memcpy(payload.get(), raw, sizeof(raw));
+
+ QUICPacketHeader *header = QUICPacketHeader::build(QUICPacketType::HANDSHAKE, 0xffddbb9977553311ULL, 0x00000001, 0, 0x00112233,
+ std::move(payload), sizeof(raw));
+ QUICPacketUPtr packet =
+ QUICPacketUPtr(new QUICPacket(header, std::move(payload), sizeof(raw), true), [](QUICPacket *p) { delete p; });
+ detector.on_packet_sent(std::move(packet));
+ ink_hrtime_sleep(HRTIME_MSECONDS(1000));
+ CHECK(tx->retransmitted.size() > 0);
+
+ // Receive ACK
+ std::shared_ptr<QUICAckFrame> frame = std::make_shared<QUICAckFrame>(0x01, 20, 0);
+ frame->ack_block_section()->add_ack_block({0, 1ULL});
+ detector.handle_frame(frame);
+ ink_hrtime_sleep(HRTIME_MSECONDS(1500));
+ int retransmit_count = tx->retransmitted.size();
+ ink_hrtime_sleep(HRTIME_MSECONDS(1500));
+ CHECK(tx->retransmitted.size() == retransmit_count);
+ }
+
+ SECTION("1-RTT")
+ {
+ // Check initial state
+ CHECK(tx->retransmitted.size() == 0);
+
+ // Send packet (1) to (7)
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet1 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet2 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet3 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet4 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet5 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet6 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet7 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet8 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+ payload = ats_unique_malloc(16);
+ QUICPacketUPtr packet9 = pf.create_server_protected_packet(connection_id, detector.largest_acked_packet_number(),
+ std::move(payload), payload_len, true);
+
+ QUICPacketNumber pn1 = packet1->packet_number();
+ QUICPacketNumber pn2 = packet2->packet_number();
+ QUICPacketNumber pn3 = packet3->packet_number();
+ QUICPacketNumber pn4 = packet4->packet_number();
+ QUICPacketNumber pn5 = packet5->packet_number();
+ QUICPacketNumber pn6 = packet6->packet_number();
+ QUICPacketNumber pn7 = packet7->packet_number();
+ QUICPacketNumber pn8 = packet8->packet_number();
+ QUICPacketNumber pn9 = packet9->packet_number();
+
+ detector.on_packet_sent(std::move(packet1));
+ detector.on_packet_sent(std::move(packet2));
+ detector.on_packet_sent(std::move(packet3));
+ detector.on_packet_sent(std::move(packet4));
+ detector.on_packet_sent(std::move(packet5));
+ detector.on_packet_sent(std::move(packet6));
+ detector.on_packet_sent(std::move(packet7));
+ detector.on_packet_sent(std::move(packet8));
+ detector.on_packet_sent(std::move(packet9));
+
+ ink_hrtime_sleep(HRTIME_MSECONDS(10000));
+
+ // Receive an ACK for (1) (4) (5) (7) (8) (9)
+ afc->update(pn1, true);
+ afc->update(pn4, true);
+ afc->update(pn5, true);
+ afc->update(pn7, true);
+ afc->update(pn8, true);
+ afc->update(pn9, true);
+ frame = afc->create();
+ detector.handle_frame(frame);
+
+ CHECK(cc->lost_packets.size() == 3);
+
+ CHECK(cc->lost_packets.find(pn1) == cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn2) != cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn3) != cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn4) == cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn5) == cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn6) != cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn7) == cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn8) == cc->lost_packets.end());
+ CHECK(cc->lost_packets.find(pn9) == cc->lost_packets.end());
+ }
}
--
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.