trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From masa...@apache.org
Subject [trafficserver] branch quic-latest updated: [draft-13] Add NEW_TOKEN frame
Date Wed, 01 Aug 2018 07:26:21 GMT
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 87526c0  [draft-13] Add NEW_TOKEN frame
87526c0 is described below

commit 87526c0d9889f7660a2a416078f7b902607bd568
Author: Masaori Koshiba <masaori@apache.org>
AuthorDate: Wed Aug 1 10:19:03 2018 +0900

    [draft-13] Add NEW_TOKEN frame
---
 iocore/net/quic/QUICFrame.cc           | 108 +++++++++++++++++++++++++++++++++
 iocore/net/quic/QUICFrame.h            |  47 +++++++++++++-
 iocore/net/quic/QUICTypes.h            |   1 +
 iocore/net/quic/test/test_QUICFrame.cc |  42 +++++++++++++
 4 files changed, 197 insertions(+), 1 deletion(-)

diff --git a/iocore/net/quic/QUICFrame.cc b/iocore/net/quic/QUICFrame.cc
index 25ef619..f0c47bf 100644
--- a/iocore/net/quic/QUICFrame.cc
+++ b/iocore/net/quic/QUICFrame.cc
@@ -44,6 +44,7 @@ ClassAllocator<QUICNewConnectionIdFrame> quicNewConnectionIdFrameAllocator("quic
 ClassAllocator<QUICStopSendingFrame> quicStopSendingFrameAllocator("quicStopSendingFrameAllocator");
 ClassAllocator<QUICPathChallengeFrame> quicPathChallengeFrameAllocator("quicPathChallengeFrameAllocator");
 ClassAllocator<QUICPathResponseFrame> quicPathResponseFrameAllocator("quicPathResponseFrameAllocator");
+ClassAllocator<QUICNewTokenFrame> quicNewTokenFrameAllocator("quicNewTokenFrameAllocator");
 ClassAllocator<QUICRetransmissionFrame> quicRetransmissionFrameAllocator("quicRetransmissionFrameAllocator");
 
 QUICFrameType
@@ -2212,6 +2213,101 @@ QUICPathResponseFrame::_data_offset() const
 }
 
 //
+// QUICNewTokenFrame
+//
+QUICFrameUPtr
+QUICNewTokenFrame::clone() const
+{
+  return QUICFrameFactory::create_new_token_frame(this->token(), this->token_length());
+}
+
+QUICFrameType
+QUICNewTokenFrame::type() const
+{
+  return QUICFrameType::NEW_TOKEN;
+}
+
+size_t
+QUICNewTokenFrame::size() const
+{
+  return this->_get_token_field_offset() + this->token_length();
+}
+
+size_t
+QUICNewTokenFrame::store(uint8_t *buf, size_t *len, size_t limit) const
+{
+  if (limit < this->size()) {
+    return 0;
+  }
+
+  if (this->_buf) {
+    *len = this->size();
+    memcpy(buf, this->_buf, *len);
+  } else {
+    uint8_t *p = buf;
+
+    // Type (i)
+    *p = static_cast<uint8_t>(QUICFrameType::NEW_TOKEN);
+    ++p;
+
+    // Token Length (i)
+    size_t n;
+    QUICIntUtil::write_QUICVariableInt(this->_token_length, p, &n);
+    p += n;
+
+    // Token (*)
+    memcpy(p, this->token(), this->token_length());
+    p += this->token_length();
+
+    *len = p - buf;
+  }
+
+  return *len;
+}
+
+uint64_t
+QUICNewTokenFrame::token_length() const
+{
+  if (this->_buf) {
+    return QUICIntUtil::read_QUICVariableInt(this->_buf + this->_get_token_length_field_offset());
+  } else {
+    return this->_token_length;
+  }
+}
+
+const uint8_t *
+QUICNewTokenFrame::token() const
+{
+  if (this->_buf) {
+    return this->_buf + this->_get_token_field_offset();
+  } else {
+    return this->_token.get();
+  }
+}
+
+size_t
+QUICNewTokenFrame::_get_token_length_field_offset() const
+{
+  return sizeof(QUICFrameType);
+}
+
+size_t
+QUICNewTokenFrame::_get_token_length_field_length() const
+{
+  if (this->_buf) {
+    return QUICVariableInt::size(this->_buf + sizeof(QUICFrameType));
+  } else {
+    return QUICVariableInt::size(this->_token_length);
+  }
+}
+
+size_t
+QUICNewTokenFrame::_get_token_field_offset() const
+{
+  return sizeof(QUICFrameType) + this->_get_token_length_field_length();
+}
+
+//
 // QUICRetransmissionFrame
 //
 QUICRetransmissionFrame::QUICRetransmissionFrame(QUICFrameUPtr original_frame, const QUICPacket
&original_packet)
@@ -2361,6 +2457,10 @@ QUICFrameFactory::create(const uint8_t *buf, size_t len)
     frame = quicPathResponseFrameAllocator.alloc();
     new (frame) QUICPathResponseFrame(buf, len);
     return QUICFrameUPtr(frame, &QUICFrameDeleter::delete_path_response_frame);
+  case QUICFrameType::NEW_TOKEN:
+    frame = quicNewTokenFrameAllocator.alloc();
+    new (frame) QUICNewTokenFrame(buf, len);
+    return QUICFrameUPtr(frame, &QUICFrameDeleter::delete_new_token_frame);
   default:
     // Unknown frame
     Debug("quic_frame_factory", "Unknown frame type %x", buf[0]);
@@ -2581,6 +2681,14 @@ QUICFrameFactory::create_new_connection_id_frame(uint32_t sequence,
QUICConnecti
   return std::unique_ptr<QUICNewConnectionIdFrame, QUICFrameDeleterFunc>(frame, &QUICFrameDeleter::delete_new_connection_id_frame);
 }
 
+std::unique_ptr<QUICNewTokenFrame, QUICFrameDeleterFunc>
+QUICFrameFactory::create_new_token_frame(const uint8_t *token, uint64_t token_len)
+{
+  QUICNewTokenFrame *frame = quicNewTokenFrameAllocator.alloc();
+  new (frame) QUICNewTokenFrame(token, token_len);
+  return std::unique_ptr<QUICNewTokenFrame, QUICFrameDeleterFunc>(frame, &QUICFrameDeleter::delete_new_token_frame);
+}
+
 std::unique_ptr<QUICRetransmissionFrame, QUICFrameDeleterFunc>
 QUICFrameFactory::create_retransmission_frame(QUICFrameUPtr original_frame, const QUICPacket
&original_packet)
 {
diff --git a/iocore/net/quic/QUICFrame.h b/iocore/net/quic/QUICFrame.h
index 05f65cb..1d5598f 100644
--- a/iocore/net/quic/QUICFrame.h
+++ b/iocore/net/quic/QUICFrame.h
@@ -326,7 +326,9 @@ public:
 private:
 };
 
+//
 // PADDING
+//
 
 class QUICPaddingFrame : public QUICFrame
 {
@@ -648,7 +650,37 @@ private:
 };
 
 //
-// Retransmission Frame
+// NEW_TOKEN
+//
+
+class QUICNewTokenFrame : public QUICFrame
+{
+public:
+  QUICNewTokenFrame() : QUICFrame() {}
+  QUICNewTokenFrame(const uint8_t *buf, size_t len, bool protection = true) : QUICFrame(buf,
len, protection) {}
+  QUICNewTokenFrame(ats_unique_buf token, size_t token_length, bool protection = true)
+    : QUICFrame(protection), _token_length(token_length), _token(std::move(token))
+  {
+  }
+  QUICFrameUPtr clone() const override;
+  virtual QUICFrameType type() const override;
+  virtual size_t size() const override;
+  virtual size_t store(uint8_t *buf, size_t *len, size_t limit) const override;
+
+  uint64_t token_length() const;
+  const uint8_t *token() const;
+
+private:
+  size_t _get_token_length_field_offset() const;
+  size_t _get_token_length_field_length() const;
+  size_t _get_token_field_offset() const;
+
+  uint64_t _token_length = 0;
+  ats_unique_buf _token  = {nullptr, [](void *p) { ats_free(p); }};
+};
+
+//
+// Retransmission Frame - Not on the spec
 //
 
 class QUICRetransmissionFrame : public QUICFrame
@@ -688,6 +720,7 @@ extern ClassAllocator<QUICNewConnectionIdFrame> quicNewConnectionIdFrameAllocato
 extern ClassAllocator<QUICStopSendingFrame> quicStopSendingFrameAllocator;
 extern ClassAllocator<QUICPathChallengeFrame> quicPathChallengeFrameAllocator;
 extern ClassAllocator<QUICPathResponseFrame> quicPathResponseFrameAllocator;
+extern ClassAllocator<QUICNewTokenFrame> quicNewTokenFrameAllocator;
 extern ClassAllocator<QUICRetransmissionFrame> quicRetransmissionFrameAllocator;
 
 class QUICFrameDeleter
@@ -827,6 +860,13 @@ public:
   }
 
   static void
+  delete_new_token_frame(QUICFrame *frame)
+  {
+    frame->~QUICFrame();
+    quicNewTokenFrameAllocator.free(static_cast<QUICNewTokenFrame *>(frame));
+  }
+
+  static void
   delete_retransmission_frame(QUICFrame *frame)
   {
     frame->~QUICFrame();
@@ -968,6 +1008,11 @@ public:
     uint32_t sequence, QUICConnectionId connectoin_id, QUICStatelessResetToken stateless_reset_token);
 
   /*
+   * Creates a NEW_TOKEN frame
+   */
+  static std::unique_ptr<QUICNewTokenFrame, QUICFrameDeleterFunc> create_new_token_frame(const
uint8_t *token, uint64_t token_len);
+
+  /*
    * Creates a retransmission frame, which is very special.
    * This retransmission frame will be used only for retransmission and it's not a standard
frame type.
    */
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 8b4df08..b58b007 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -109,6 +109,7 @@ enum class QUICFrameType : uint8_t {
   PATH_RESPONSE,
   STREAM = 0x10, // 0x10 - 0x17
   CRYPTO = 0x18,
+  NEW_TOKEN,
   UNKNOWN,
 };
 
diff --git a/iocore/net/quic/test/test_QUICFrame.cc b/iocore/net/quic/test/test_QUICFrame.cc
index 6a32a46..ad67a6f 100644
--- a/iocore/net/quic/test/test_QUICFrame.cc
+++ b/iocore/net/quic/test/test_QUICFrame.cc
@@ -49,6 +49,7 @@ TEST_CASE("QUICFrame Type", "[quic]")
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x10")) == QUICFrameType::STREAM);
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x17")) == QUICFrameType::STREAM);
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x18")) == QUICFrameType::CRYPTO);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x19")) == QUICFrameType::NEW_TOKEN);
   // Undefined ragne
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x21")) == QUICFrameType::UNKNOWN);
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xff")) == QUICFrameType::UNKNOWN);
@@ -1133,6 +1134,47 @@ TEST_CASE("Store PATH_RESPONSE Frame", "[quic]")
   CHECK(memcmp(buf, expected, len) == 0);
 }
 
+TEST_CASE("NEW_TOKEN Frame", "[quic]")
+{
+  uint8_t raw_new_token_frame[] = {
+    0x19,                                           // Type
+    0x08,                                           // Token Length (i)
+    0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, // Token (*)
+  };
+  size_t raw_new_token_frame_len = sizeof(raw_new_token_frame);
+
+  uint8_t raw_token[]  = {0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef, 0xbe, 0xef};
+  size_t raw_token_len = sizeof(raw_token);
+
+  SECTION("load")
+  {
+    std::shared_ptr<const QUICFrame> frame = QUICFrameFactory::create(raw_new_token_frame,
raw_new_token_frame_len);
+    CHECK(frame->type() == QUICFrameType::NEW_TOKEN);
+    CHECK(frame->size() == raw_new_token_frame_len);
+
+    std::shared_ptr<const QUICNewTokenFrame> new_token_frame = std::dynamic_pointer_cast<const
QUICNewTokenFrame>(frame);
+    CHECK(new_token_frame != nullptr);
+    CHECK(new_token_frame->token_length() == raw_token_len);
+    CHECK(memcmp(new_token_frame->token(), raw_token, raw_token_len) == 0);
+  }
+
+  SECTION("store")
+  {
+    uint8_t buf[32];
+    size_t len;
+
+    ats_unique_buf token = ats_unique_malloc(raw_token_len);
+    memcpy(token.get(), raw_token, raw_token_len);
+
+    QUICNewTokenFrame frame(std::move(token), raw_token_len);
+    CHECK(frame.size() == raw_new_token_frame_len);
+
+    frame.store(buf, &len, 16);
+    CHECK(len == raw_new_token_frame_len);
+    CHECK(memcmp(buf, raw_new_token_frame, len) == 0);
+  }
+}
+
 TEST_CASE("QUICFrameFactory Create Unknown Frame", "[quic]")
 {
   uint8_t buf1[] = {


Mime
View raw message