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 2018/08/24 07:02:19 UTC
[trafficserver] branch quic-latest updated (0a2fd36 -> 7a19546)
This is an automated email from the ASF dual-hosted git repository.
masaori pushed a change to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git.
from 0a2fd36 Cleanup: Remove QUICPacketTransmitter::transmit_packet()
new 253ee35 Cleanup debug logs of Loss Detector
new 7a19546 Send BLOCKED frame
The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
iocore/net/QUICNetVConnection.cc | 22 +++++++++----
iocore/net/quic/QUICDebugNames.cc | 15 +++++++++
iocore/net/quic/QUICDebugNames.h | 1 +
iocore/net/quic/QUICFlowController.cc | 6 ++--
iocore/net/quic/QUICLossDetector.cc | 30 +++++++++--------
iocore/net/quic/QUICStream.cc | 17 ++++++++--
iocore/net/quic/test/test_QUICFlowController.cc | 43 ++++++++++++++++++++++---
7 files changed, 105 insertions(+), 29 deletions(-)
[trafficserver] 01/02: Cleanup debug logs of Loss Detector
Posted by ma...@apache.org.
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 253ee352ede1edd115d59fd1bdd433a94273e1c9
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Thu Aug 23 15:47:39 2018 +0900
Cleanup debug logs of Loss Detector
---
iocore/net/quic/QUICDebugNames.cc | 15 +++++++++++++++
iocore/net/quic/QUICDebugNames.h | 1 +
iocore/net/quic/QUICLossDetector.cc | 30 ++++++++++++++++--------------
3 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/iocore/net/quic/QUICDebugNames.cc b/iocore/net/quic/QUICDebugNames.cc
index 01aecf3..de86f8e 100644
--- a/iocore/net/quic/QUICDebugNames.cc
+++ b/iocore/net/quic/QUICDebugNames.cc
@@ -274,3 +274,18 @@ QUICDebugNames::encryption_level(QUICEncryptionLevel level)
return "UNKNOWN";
}
}
+
+const char *
+QUICDebugNames::pn_space(int index)
+{
+ switch (index) {
+ case 0:
+ return "INITIAL";
+ case 1:
+ return "PROTECTED";
+ case 2:
+ return "HANDSHAKE";
+ default:
+ return "UNKNOWN";
+ }
+}
diff --git a/iocore/net/quic/QUICDebugNames.h b/iocore/net/quic/QUICDebugNames.h
index 2322299..b2ce4ec 100644
--- a/iocore/net/quic/QUICDebugNames.h
+++ b/iocore/net/quic/QUICDebugNames.h
@@ -40,6 +40,7 @@ public:
static const char *quic_event(int event);
static const char *key_phase(QUICKeyPhase phase);
static const char *encryption_level(QUICEncryptionLevel level);
+ static const char *pn_space(int index);
};
class QUICDebug
diff --git a/iocore/net/quic/QUICLossDetector.cc b/iocore/net/quic/QUICLossDetector.cc
index de3c864..548ee9b 100644
--- a/iocore/net/quic/QUICLossDetector.cc
+++ b/iocore/net/quic/QUICLossDetector.cc
@@ -27,11 +27,14 @@
#include "QUICConfig.h"
#include "QUICEvents.h"
+#include "QUICDebugNames.h"
-#define QUICLDDebug(fmt, ...) \
- Debug("quic_loss_detector", "[%s] [PNS-%d] " fmt, this->_info->cids().data(), this->_pn_space_index, ##__VA_ARGS__)
-#define QUICLDVDebug(fmt, ...) \
- Debug("v_quic_loss_detector", "[%s] [PNS-%d] " fmt, this->_info->cids().data(), this->_pn_space_index, ##__VA_ARGS__)
+#define QUICLDDebug(fmt, ...) \
+ Debug("quic_loss_detector", "[%s] [%s] " fmt, this->_info->cids().data(), QUICDebugNames::pn_space(this->_pn_space_index), \
+ ##__VA_ARGS__)
+#define QUICLDVDebug(fmt, ...) \
+ Debug("v_quic_loss_detector", "[%s] [%s] " fmt, this->_info->cids().data(), QUICDebugNames::pn_space(this->_pn_space_index), \
+ ##__VA_ARGS__)
QUICLossDetector::QUICLossDetector(QUICPacketTransmitter *transmitter, QUICConnectionInfoProvider *info,
QUICCongestionController *cc, QUICRTTMeasure *rtt_measure, int index)
@@ -223,8 +226,8 @@ QUICLossDetector::_on_ack_received(const std::shared_ptr<const QUICAckFrame> &ac
this->_update_rtt(this->_latest_rtt, delay, ack_frame->largest_acknowledged());
}
- QUICLDDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
- this->_retransmittable_outstanding.load(), this->_handshake_outstanding.load());
+ QUICLDVDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
+ this->_retransmittable_outstanding.load(), this->_handshake_outstanding.load());
// Find all newly acked packets.
for (auto &&range : this->_determine_newly_acked_packets(*ack_frame)) {
@@ -238,8 +241,8 @@ QUICLossDetector::_on_ack_received(const std::shared_ptr<const QUICAckFrame> &ac
}
}
- QUICLDDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
- this->_retransmittable_outstanding.load(), this->_handshake_outstanding.load());
+ QUICLDVDebug("Unacked packets %lu (retransmittable %u, includes %u handshake packets)", this->_sent_packets.size(),
+ this->_retransmittable_outstanding.load(), this->_handshake_outstanding.load());
this->_detect_lost_packets(ack_frame->largest_acknowledged());
@@ -384,7 +387,7 @@ QUICLossDetector::_on_loss_detection_alarm()
this->_detect_lost_packets(this->_largest_acked_packet);
} else if (this->_tlp_count < this->_k_max_tlps) {
// Tail Loss Probe.
- QUICLDDebug("TLP");
+ QUICLDVDebug("TLP");
// FIXME TLP causes inifinite loop somehow
// this->_send_one_packet();
this->_tlp_count++;
@@ -393,7 +396,7 @@ QUICLossDetector::_on_loss_detection_alarm()
if (this->_rto_count == 0) {
this->_largest_sent_before_rto = this->_largest_sent_packet;
}
- QUICLDDebug("RTO");
+ QUICLDVDebug("RTO");
this->_send_two_packets();
this->_rto_count++;
}
@@ -435,14 +438,13 @@ QUICLossDetector::_detect_lost_packets(QUICPacketNumber largest_acked_packet_num
uint64_t delta = largest_acked_packet_number - it->second->packet_number;
if (time_since_sent > delay_until_lost || delta > this->_reordering_threshold) {
if (time_since_sent > delay_until_lost) {
- QUICLDDebug("Lost: time since sent is too long (PN=%" PRId64 " sent=%" PRId64 ", delay=%lf, fraction=%lf, lrtt=%" PRId64
+ QUICLDDebug("Lost: time since sent is too long (#%" PRId64 " sent=%" PRId64 ", delay=%lf, fraction=%lf, lrtt=%" PRId64
", srtt=%" PRId64 ")",
it->first, time_since_sent, delay_until_lost, this->_time_reordering_fraction, this->_latest_rtt,
this->_smoothed_rtt);
} else {
- QUICLDDebug("Lost: packet delta is too large (PN=%" PRId64 " largest=%" PRId64 " unacked=%" PRId64 " threshold=%" PRId32
- ")",
- it->first, largest_acked_packet_number, it->second->packet_number, this->_reordering_threshold);
+ QUICLDDebug("Lost: packet delta is too large (#%" PRId64 " largest=%" PRId64 " threshold=%" PRId32 ")", it->first,
+ largest_acked_packet_number, this->_reordering_threshold);
}
if (!it->second->ack_only) {
[trafficserver] 02/02: Send BLOCKED frame
Posted by ma...@apache.org.
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 7a195464eca6c51c491dfb14d6343e06f863ac46
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Thu Aug 23 16:05:16 2018 +0900
Send BLOCKED frame
QUICRemoteFlowController::update() create BLOCKED(_STREAM) frame. It will be sent when STREAMs have anything to send.
---
iocore/net/QUICNetVConnection.cc | 22 +++++++++----
iocore/net/quic/QUICFlowController.cc | 6 ++--
iocore/net/quic/QUICStream.cc | 17 ++++++++--
iocore/net/quic/test/test_QUICFlowController.cc | 43 ++++++++++++++++++++++---
4 files changed, 73 insertions(+), 15 deletions(-)
diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc
index 03fde79..a019f9b 100644
--- a/iocore/net/QUICNetVConnection.cc
+++ b/iocore/net/QUICNetVConnection.cc
@@ -1214,7 +1214,8 @@ QUICNetVConnection::_packetize_frames(QUICEncryptionLevel level, uint64_t max_pa
bool ack_only = true;
if (this->_connection_error || this->_packet_retransmitter.will_generate_frame(level) ||
this->_handshake_handler->will_generate_frame(level) || this->_stream_manager->will_generate_frame(level) ||
- this->_path_validator->will_generate_frame(level)) {
+ this->_path_validator->will_generate_frame(level) || this->_local_flow_controller->will_generate_frame(level) ||
+ (this->_stream_manager->will_generate_frame(level) && this->_remote_flow_controller->will_generate_frame(level))) {
ack_only = false;
}
@@ -1241,7 +1242,7 @@ QUICNetVConnection::_packetize_frames(QUICEncryptionLevel level, uint64_t max_pa
}
// PATH_CHALLENGE, PATH_RESPOSNE
- frame = this->_path_validator->generate_frame(level, this->_remote_flow_controller->credit(), max_frame_size);
+ frame = this->_path_validator->generate_frame(level, UINT16_MAX, max_frame_size);
if (frame) {
++frame_count;
this->_store_frame(buf, len, max_frame_size, std::move(frame));
@@ -1249,22 +1250,31 @@ QUICNetVConnection::_packetize_frames(QUICEncryptionLevel level, uint64_t max_pa
// NEW_CONNECTION_ID
if (this->_alt_con_manager) {
- frame = this->_alt_con_manager->generate_frame(level, this->_remote_flow_controller->credit(), max_frame_size);
+ frame = this->_alt_con_manager->generate_frame(level, UINT16_MAX, max_frame_size);
while (frame) {
++frame_count;
this->_store_frame(buf, len, max_frame_size, std::move(frame));
- frame = this->_alt_con_manager->generate_frame(level, this->_remote_flow_controller->credit(), max_frame_size);
+ frame = this->_alt_con_manager->generate_frame(level, UINT16_MAX, max_frame_size);
}
}
// Lost frames
- frame = this->_packet_retransmitter.generate_frame(level, this->_remote_flow_controller->credit(), max_frame_size);
+ frame = this->_packet_retransmitter.generate_frame(level, UINT16_MAX, max_frame_size);
while (frame) {
++frame_count;
this->_store_frame(buf, len, max_frame_size, std::move(frame));
- frame = this->_packet_retransmitter.generate_frame(level, this->_remote_flow_controller->credit(), max_frame_size);
+ frame = this->_packet_retransmitter.generate_frame(level, UINT16_MAX, max_frame_size);
+ }
+
+ // BLOCKED
+ if (this->_remote_flow_controller->credit() == 0 && this->_stream_manager->will_generate_frame(level)) {
+ frame = this->_remote_flow_controller->generate_frame(level, UINT16_MAX, max_frame_size);
+ if (frame) {
+ ++frame_count;
+ this->_store_frame(buf, len, max_frame_size, std::move(frame));
+ }
}
// STREAM, MAX_STREAM_DATA, STREAM_BLOCKED
diff --git a/iocore/net/quic/QUICFlowController.cc b/iocore/net/quic/QUICFlowController.cc
index 57357f1..70ff181 100644
--- a/iocore/net/quic/QUICFlowController.cc
+++ b/iocore/net/quic/QUICFlowController.cc
@@ -100,6 +100,7 @@ QUICFlowController::set_limit(QUICOffset limit)
this->_limit = limit;
}
+// For RemoteFlowController, caller of this function should also check QUICStreamManager::will_generate_frame()
bool
QUICFlowController::will_generate_frame(QUICEncryptionLevel level)
{
@@ -142,8 +143,9 @@ QUICRemoteFlowController::update(QUICOffset offset)
{
int ret = QUICFlowController::update(offset);
- // Send BLOCKED(_STREAM) frame
- if (!this->_blocked && offset > this->_limit) {
+ // Create BLOCKED(_STREAM) frame
+ // The frame will be sent if stream has something to send.
+ if (!this->_blocked && offset >= this->_limit) {
this->_frame = this->_create_frame();
this->_blocked = true;
}
diff --git a/iocore/net/quic/QUICStream.cc b/iocore/net/quic/QUICStream.cc
index ff38147..d2a5a3f 100644
--- a/iocore/net/quic/QUICStream.cc
+++ b/iocore/net/quic/QUICStream.cc
@@ -403,6 +403,10 @@ QUICStream::generate_frame(QUICEncryptionLevel level, uint64_t connection_credit
return frame;
}
+ if (connection_credit == 0) {
+ return frame;
+ }
+
if (maximum_frame_size <= MAX_STREAM_FRAME_OVERHEAD) {
return frame;
}
@@ -413,13 +417,20 @@ QUICStream::generate_frame(QUICEncryptionLevel level, uint64_t connection_credit
return frame;
}
+ // STREAM_BLOCKED
+ uint64_t stream_credit = this->_remote_flow_controller.credit();
+ // The `bytes_avail` should be also checked before calling QUICRemoteFlowController::generate_frame(), but we don't need it.
+ // Because it's already checked in above.
+ if (stream_credit == 0) {
+ frame = this->_remote_flow_controller.generate_frame(level, connection_credit, maximum_frame_size);
+ }
+
int64_t data_len = reader->block_read_avail();
int64_t len = 0;
bool fin = false;
- len = std::min(data_len, static_cast<int64_t>(
- std::min(static_cast<uint64_t>(maximum_frame_size - MAX_STREAM_FRAME_OVERHEAD),
- std::min(this->_remote_flow_controller.credit(), static_cast<uint64_t>(connection_credit)))));
+ len = std::min(data_len, static_cast<int64_t>(std::min(static_cast<uint64_t>(maximum_frame_size - MAX_STREAM_FRAME_OVERHEAD),
+ std::min(stream_credit, static_cast<uint64_t>(connection_credit)))));
if (this->_write_vio.nbytes == static_cast<int64_t>(this->_send_offset + len)) {
fin = true;
diff --git a/iocore/net/quic/test/test_QUICFlowController.cc b/iocore/net/quic/test/test_QUICFlowController.cc
index 0d8749c..951a0e5 100644
--- a/iocore/net/quic/test/test_QUICFlowController.cc
+++ b/iocore/net/quic/test/test_QUICFlowController.cc
@@ -132,20 +132,20 @@ TEST_CASE("QUICFlowController_Remote_Connection", "[quic]")
CHECK(fc.current_limit() == 1024);
CHECK(ret == 0);
- ret = fc.update(1024);
- CHECK(fc.current_offset() == 1024);
+ ret = fc.update(1000);
+ CHECK(fc.current_offset() == 1000);
CHECK(fc.current_limit() == 1024);
CHECK(ret == 0);
// Delay
ret = fc.update(512);
- CHECK(fc.current_offset() == 1024);
+ CHECK(fc.current_offset() == 1000);
CHECK(fc.current_limit() == 1024);
CHECK(ret == 0);
// Exceed limit
ret = fc.update(1280);
- CHECK(fc.current_offset() == 1024);
+ CHECK(fc.current_offset() == 1000);
CHECK(fc.current_limit() == 1024);
CHECK(ret != 0);
QUICFrameUPtr frame = fc.generate_frame(QUICEncryptionLevel::ONE_RTT, 0, 1024);
@@ -154,6 +154,38 @@ TEST_CASE("QUICFlowController_Remote_Connection", "[quic]")
// MAX_STREAM_DATA
fc.forward_limit(2048);
+ CHECK(fc.current_offset() == 1000);
+ CHECK(fc.current_limit() == 2048);
+
+ ret = fc.update(1280);
+ CHECK(fc.current_offset() == 1280);
+ CHECK(fc.current_limit() == 2048);
+ CHECK(ret == 0);
+}
+
+TEST_CASE("QUICFlowController_Remote_Connection_ZERO_Credit", "[quic]")
+{
+ int ret = 0;
+ QUICRemoteConnectionFlowController fc(1024);
+
+ // Check initial state
+ CHECK(fc.current_offset() == 0);
+ CHECK(fc.current_limit() == 1024);
+
+ // Zero credit
+ ret = fc.update(1024);
+ CHECK(fc.current_offset() == 1024);
+ CHECK(fc.current_limit() == 1024);
+ CHECK(ret == 0);
+
+ CHECK(fc.will_generate_frame(QUICEncryptionLevel::ONE_RTT));
+ // if there're anything to send
+ QUICFrameUPtr frame = fc.generate_frame(QUICEncryptionLevel::ONE_RTT, 0, 1024);
+ CHECK(frame);
+ CHECK(frame->type() == QUICFrameType::BLOCKED);
+
+ // MAX_STREAM_DATA
+ fc.forward_limit(2048);
CHECK(fc.current_offset() == 1024);
CHECK(fc.current_limit() == 2048);
@@ -251,6 +283,9 @@ TEST_CASE("QUICFlowController_Remote_Stream", "[quic]")
CHECK(fc.current_limit() == 1024);
CHECK(ret == 0);
+ CHECK(fc.credit() == 0);
+ CHECK(fc.will_generate_frame(QUICEncryptionLevel::ONE_RTT));
+
// Delay
ret = fc.update(512);
CHECK(fc.current_offset() == 1024);