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/18 05:21:53 UTC
[trafficserver] branch quic-latest updated: draft-08: Support new
PING/PONG frame format
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
The following commit(s) were added to refs/heads/quic-latest by this push:
new 72056a6 draft-08: Support new PING/PONG frame format
72056a6 is described below
commit 72056a67d53bf232ae56391f6ca75d9c8d080c8c
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Mon Dec 18 14:21:39 2017 +0900
draft-08: Support new PING/PONG frame format
---
iocore/net/quic/QUICDebugNames.cc | 2 +
iocore/net/quic/QUICFrame.cc | 96 ++++++++++++++++++++++++++-
iocore/net/quic/QUICFrame.h | 45 +++++++++++++
iocore/net/quic/test/test_QUICFrame.cc | 114 +++++++++++++++++++++++++++++----
4 files changed, 242 insertions(+), 15 deletions(-)
diff --git a/iocore/net/quic/QUICDebugNames.cc b/iocore/net/quic/QUICDebugNames.cc
index e08a910..a96bf39 100644
--- a/iocore/net/quic/QUICDebugNames.cc
+++ b/iocore/net/quic/QUICDebugNames.cc
@@ -78,6 +78,8 @@ QUICDebugNames::frame_type(QUICFrameType type)
return "ACK";
case QUICFrameType::STREAM:
return "STREAM";
+ case QUICFrameType::PONG:
+ return "PONG";
case QUICFrameType::UNKNOWN:
default:
return "UNKNOWN";
diff --git a/iocore/net/quic/QUICFrame.cc b/iocore/net/quic/QUICFrame.cc
index 6160b26..93d894c 100644
--- a/iocore/net/quic/QUICFrame.cc
+++ b/iocore/net/quic/QUICFrame.cc
@@ -39,6 +39,7 @@ ClassAllocator<QUICStreamBlockedFrame> quicStreamBlockedFrameAllocator("quicStre
ClassAllocator<QUICStreamIdBlockedFrame> quicStreamIdBlockedFrameAllocator("quicStreamIdBlockedFrameAllocator");
ClassAllocator<QUICNewConnectionIdFrame> quicNewConnectionIdFrameAllocator("quicNewConnectionIdFrameAllocator");
ClassAllocator<QUICStopSendingFrame> quicStopSendingFrameAllocator("quicStopSendingFrameAllocator");
+ClassAllocator<QUICPongFrame> quicPongFrameAllocator("quicPongFrameAllocator");
ClassAllocator<QUICRetransmissionFrame> quicRetransmissionFrameAllocator("quicRetransmissionFrameAllocator");
QUICFrameType
@@ -795,21 +796,50 @@ QUICPingFrame::type() const
size_t
QUICPingFrame::size() const
{
- return 1;
+ return this->_data_offset() + this->data_length();
}
void
QUICPingFrame::store(uint8_t *buf, size_t *len) const
{
+ *len = this->size();
+
if (this->_buf) {
- *len = this->size();
memcpy(buf, this->_buf, *len);
} else {
buf[0] = static_cast<uint8_t>(QUICFrameType::PING);
- *len = 1;
+ buf[1] = this->data_length();
+
+ memcpy(buf + this->_data_offset(), this->data(), this->data_length());
+ }
+}
+
+const uint8_t *
+QUICPingFrame::data() const
+{
+ if (this->_buf) {
+ return this->_buf + this->_data_offset();
+ } else {
+ return this->_data.get();
}
}
+uint8_t
+QUICPingFrame::data_length() const
+{
+ if (this->_buf) {
+ return QUICTypeUtil::read_nbytes_as_uint(this->_buf + sizeof(QUICFrameType), 1);
+ } else {
+ return this->_data_len;
+ }
+}
+
+const size_t
+QUICPingFrame::_data_offset() const
+{
+ return sizeof(QUICFrameType) + sizeof(this->_data_len);
+}
+
//
// PADDING frame
//
@@ -1592,6 +1622,62 @@ QUICStopSendingFrame::_get_error_code_field_offset() const
}
//
+// PONG frame
+//
+QUICFrameType
+QUICPongFrame::type() const
+{
+ return QUICFrameType::PONG;
+}
+
+size_t
+QUICPongFrame::size() const
+{
+ return this->_data_offset() + this->data_length();
+}
+
+void
+QUICPongFrame::store(uint8_t *buf, size_t *len) const
+{
+ *len = this->size();
+
+ if (this->_buf) {
+ memcpy(buf, this->_buf, *len);
+ } else {
+ buf[0] = static_cast<uint8_t>(QUICFrameType::PONG);
+ buf[1] = this->data_length();
+
+ memcpy(buf + this->_data_offset(), this->data(), this->data_length());
+ }
+}
+
+const uint8_t *
+QUICPongFrame::data() const
+{
+ if (this->_buf) {
+ return this->_buf + this->_data_offset();
+ } else {
+ return this->_data.get();
+ }
+}
+
+uint8_t
+QUICPongFrame::data_length() const
+{
+ if (this->_buf) {
+ return QUICTypeUtil::read_nbytes_as_uint(this->_buf + sizeof(QUICFrameType), 1);
+ } else {
+ return this->_data_len;
+ }
+}
+
+const size_t
+QUICPongFrame::_data_offset() const
+{
+ return sizeof(QUICFrameType) + sizeof(this->_data_len);
+}
+
+//
// QUICRetransmissionFrame
//
QUICRetransmissionFrame::QUICRetransmissionFrame(QUICFrameUPtr original_frame, const QUICPacket &original_packet)
@@ -1705,6 +1791,10 @@ QUICFrameFactory::create(const uint8_t *buf, size_t len)
frame = quicStopSendingFrameAllocator.alloc();
new (frame) QUICStopSendingFrame(buf, len);
return QUICFrameUPtr(frame, &QUICFrameDeleter::delete_stop_sending_frame);
+ case QUICFrameType::PONG:
+ frame = quicPongFrameAllocator.alloc();
+ new (frame) QUICPongFrame(buf, len);
+ return QUICFrameUPtr(frame, &QUICFrameDeleter::delete_pong_frame);
default:
// Unknown frame
Debug("quic_frame_factory", "Unknown frame type %x", buf[0]);
diff --git a/iocore/net/quic/QUICFrame.h b/iocore/net/quic/QUICFrame.h
index 74e03a8..df5bf75 100644
--- a/iocore/net/quic/QUICFrame.h
+++ b/iocore/net/quic/QUICFrame.h
@@ -59,9 +59,11 @@ public:
QUICStreamFrame() : QUICFrame() {}
QUICStreamFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {}
QUICStreamFrame(ats_unique_buf buf, size_t len, QUICStreamId streamid, QUICOffset offset, bool last = false);
+
virtual QUICFrameType type() const override;
virtual size_t size() const override;
virtual void store(uint8_t *buf, size_t *len) const override;
+
void store(uint8_t *buf, size_t *len, bool include_length_field) const;
QUICStreamId stream_id() const;
QUICOffset offset() const;
@@ -229,9 +231,20 @@ class QUICPingFrame : public QUICFrame
public:
QUICPingFrame() : QUICFrame() {}
QUICPingFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {}
+ QUICPingFrame(ats_unique_buf data, size_t data_len) : _data(std::move(data)), _data_len(data_len) {}
+
virtual QUICFrameType type() const override;
virtual size_t size() const override;
virtual void store(uint8_t *buf, size_t *len) const override;
+
+ const uint8_t *data() const;
+ uint8_t data_length() const;
+
+private:
+ const size_t _data_offset() const;
+
+ ats_unique_buf _data = {nullptr, [](void *p) { ats_free(p); }};
+ uint8_t _data_len = 0;
};
// PADDING
@@ -499,6 +512,31 @@ using QUICFrameUPtr = std::unique_ptr<QUICFrame, QUICFrameDeleterFunc>;
using QUICStreamFrameUPtr = std::unique_ptr<QUICStreamFrame, QUICFrameDeleterFunc>;
//
+// PONG
+//
+
+class QUICPongFrame : public QUICFrame
+{
+public:
+ QUICPongFrame() : QUICFrame() {}
+ QUICPongFrame(const uint8_t *buf, size_t len) : QUICFrame(buf, len) {}
+ QUICPongFrame(ats_unique_buf data, size_t data_len) : _data(std::move(data)), _data_len(data_len) {}
+
+ virtual QUICFrameType type() const override;
+ virtual size_t size() const override;
+ virtual void store(uint8_t *buf, size_t *len) const override;
+
+ const uint8_t *data() const;
+ uint8_t data_length() const;
+
+private:
+ const size_t _data_offset() const;
+
+ ats_unique_buf _data = {nullptr, [](void *p) { ats_free(p); }};
+ uint8_t _data_len = 0;
+};
+
+//
// Retransmission Frame
//
@@ -533,6 +571,7 @@ extern ClassAllocator<QUICStreamBlockedFrame> quicStreamBlockedFrameAllocator;
extern ClassAllocator<QUICStreamIdBlockedFrame> quicStreamIdBlockedFrameAllocator;
extern ClassAllocator<QUICNewConnectionIdFrame> quicNewConnectionIdFrameAllocator;
extern ClassAllocator<QUICStopSendingFrame> quicStopSendingFrameAllocator;
+extern ClassAllocator<QUICPongFrame> quicPongFrameAllocator;
extern ClassAllocator<QUICRetransmissionFrame> quicRetransmissionFrameAllocator;
class QUICFrameDeleter
@@ -637,6 +676,12 @@ public:
}
static void
+ delete_pong_frame(QUICFrame *frame)
+ {
+ quicPongFrameAllocator.free(static_cast<QUICPongFrame *>(frame));
+ }
+
+ static void
delete_retransmission_frame(QUICFrame *frame)
{
quicRetransmissionFrameAllocator.free(static_cast<QUICRetransmissionFrame *>(frame));
diff --git a/iocore/net/quic/test/test_QUICFrame.cc b/iocore/net/quic/test/test_QUICFrame.cc
index b3aee21..e23dd6a 100644
--- a/iocore/net/quic/test/test_QUICFrame.cc
+++ b/iocore/net/quic/test/test_QUICFrame.cc
@@ -495,27 +495,42 @@ TEST_CASE("Store RST_STREAM Frame", "[quic]")
TEST_CASE("Load Ping Frame", "[quic]")
{
- uint8_t buf1[] = {
- 0x07, // Type
+ uint8_t buf[] = {
+ 0x07, // Type
+ 0x08, // Length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
};
- std::shared_ptr<const QUICFrame> frame1 = QUICFrameFactory::create(buf1, sizeof(buf1));
- CHECK(frame1->type() == QUICFrameType::PING);
- CHECK(frame1->size() == 1);
- std::shared_ptr<const QUICPingFrame> ping_frame = std::dynamic_pointer_cast<const QUICPingFrame>(frame1);
+ std::shared_ptr<const QUICFrame> frame = QUICFrameFactory::create(buf, sizeof(buf));
+ CHECK(frame->type() == QUICFrameType::PING);
+ CHECK(frame->size() == 10);
+
+ std::shared_ptr<const QUICPingFrame> ping_frame = std::dynamic_pointer_cast<const QUICPingFrame>(frame);
CHECK(ping_frame != nullptr);
+ CHECK(ping_frame->data_length() == 8);
+ CHECK(memcmp(ping_frame->data(), "\x01\x23\x45\x67\x89\xab\xcd\xef", 8) == 0);
}
TEST_CASE("Store Ping Frame", "[quic]")
{
- uint8_t buf[65535];
+ uint8_t buf[16];
size_t len;
uint8_t expected[] = {
- 0x07, // Type
+ 0x07, // Type
+ 0x08, // Length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
};
- QUICPingFrame ping_frame;
- ping_frame.store(buf, &len);
- CHECK(len == 1);
+
+ uint8_t raw[] = "\x01\x23\x45\x67\x89\xab\xcd\xef";
+ size_t raw_len = sizeof(raw) - 1;
+ ats_unique_buf data = ats_unique_malloc(raw_len);
+ memcpy(data.get(), raw, raw_len);
+
+ QUICPingFrame frame(std::move(data), 8);
+ CHECK(frame.size() == 10);
+
+ frame.store(buf, &len);
+ CHECK(len == 10);
CHECK(memcmp(buf, expected, len) == 0);
}
@@ -974,6 +989,47 @@ TEST_CASE("Store STOP_SENDING Frame", "[quic]")
CHECK(memcmp(buf, expected, len) == 0);
}
+TEST_CASE("Load Pong Frame", "[quic]")
+{
+ uint8_t buf[] = {
+ 0x0d, // Type
+ 0x08, // Length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
+ };
+ std::shared_ptr<const QUICFrame> frame = QUICFrameFactory::create(buf, sizeof(buf));
+ CHECK(frame->type() == QUICFrameType::PONG);
+ CHECK(frame->size() == 10);
+
+ std::shared_ptr<const QUICPongFrame> pong_frame = std::dynamic_pointer_cast<const QUICPongFrame>(frame);
+ CHECK(pong_frame != nullptr);
+ CHECK(pong_frame->data_length() == 8);
+ CHECK(memcmp(pong_frame->data(), "\x01\x23\x45\x67\x89\xab\xcd\xef", 8) == 0);
+}
+
+TEST_CASE("Store Pong Frame", "[quic]")
+{
+ uint8_t buf[16];
+ size_t len;
+
+ uint8_t expected[] = {
+ 0x0d, // Type
+ 0x08, // Length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
+ };
+
+ uint8_t raw[] = "\x01\x23\x45\x67\x89\xab\xcd\xef";
+ size_t raw_len = sizeof(raw) - 1;
+ ats_unique_buf data = ats_unique_malloc(raw_len);
+ memcpy(data.get(), raw, raw_len);
+
+ QUICPongFrame frame(std::move(data), 8);
+ CHECK(frame.size() == 10);
+
+ frame.store(buf, &len);
+ CHECK(len == 10);
+ CHECK(memcmp(buf, expected, len) == 0);
+}
+
TEST_CASE("QUICFrameFactory Create Unknown Frame", "[quic]")
{
uint8_t buf1[] = {
@@ -1054,6 +1110,7 @@ TEST_CASE("QUICFrameFactory Create RST_STREAM with a QUICStreamError", "[quic]")
CHECK(rst_stream_frame1->final_offset() == 0);
}
+// Test for retransmittable frames
TEST_CASE("Retransmit", "[quic][frame][retransmit]")
{
QUICPacketFactory factory;
@@ -1198,7 +1255,21 @@ TEST_CASE("Retransmit", "[quic][frame][retransmit]")
SECTION("PING frame")
{
- // TODO
+ uint8_t frame_buf[] = {
+ 0x07, // Type
+ 0x08, // Length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
+ };
+
+ QUICFrameUPtr frame = QUICFrameFactory::create(frame_buf, sizeof(frame_buf));
+ frame = QUICFrameFactory::create_retransmission_frame(std::move(frame), *packet);
+
+ uint8_t buf[32] = {0};
+ size_t len;
+ frame->store(buf, &len);
+
+ CHECK(len == 10);
+ CHECK(memcmp(buf, frame_buf, len) == 0);
}
SECTION("BLOCKED frame")
@@ -1295,4 +1366,23 @@ TEST_CASE("Retransmit", "[quic][frame][retransmit]")
CHECK(len == 7);
CHECK(memcmp(buf, frame_buf, len) == 0);
}
+
+ SECTION("PONG frame")
+ {
+ uint8_t frame_buf[] = {
+ 0x0d, // Type
+ 0x08, // Length
+ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, // Data
+ };
+
+ QUICFrameUPtr frame = QUICFrameFactory::create(frame_buf, sizeof(frame_buf));
+ frame = QUICFrameFactory::create_retransmission_frame(std::move(frame), *packet);
+
+ uint8_t buf[32] = {0};
+ size_t len;
+ frame->store(buf, &len);
+
+ CHECK(len == 10);
+ CHECK(memcmp(buf, frame_buf, len) == 0);
+ }
}
--
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].