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:32 UTC

[trafficserver] branch quic-latest updated (069f3e8 -> 25fc8ab)

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 069f3e8  Merge branch 'master' into quic-latest
     new 3877887  draft-08: Support long header packet type & format
     new 624c5c7  draft-08: Support short header packet type & format
     new ab3a06b  Fix QUICPacketLongHeader::store for new long header format
     new c90274a  draft-08: Bump version
     new af62ebd  Parse and create ack block in draft-08 way
     new 7e7e3fc  draft-08: Support Variable-Length Integer Encoding
     new 3d3b174  draft-08: Adjust frame types
     new 25fc8ab  draft-08: Support new STREAM frame format

The 8 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/P_QUICNetVConnection.h                  |   8 +-
 iocore/net/QUICNetVConnection.cc                   |  26 +-
 iocore/net/quic/Mock.h                             |  60 ++--
 iocore/net/quic/QUICAckFrameCreator.cc             |   8 +-
 iocore/net/quic/QUICApplication.cc                 |   2 +-
 iocore/net/quic/QUICCongestionController.cc        |  20 ++
 iocore/net/quic/QUICCongestionController.h         |   9 +-
 iocore/net/quic/QUICDebugNames.cc                  |  14 +-
 iocore/net/quic/QUICEchoApp.cc                     |   2 +-
 iocore/net/quic/QUICFrame.cc                       | 221 ++++++++------
 iocore/net/quic/QUICFrame.h                        |  20 +-
 iocore/net/quic/QUICHandshake.cc                   |   2 +-
 iocore/net/quic/QUICLossDetector.cc                |  21 +-
 iocore/net/quic/QUICLossDetector.h                 |   4 +-
 iocore/net/quic/QUICPacket.cc                      |  93 +++---
 iocore/net/quic/QUICPacket.h                       |   8 +-
 iocore/net/quic/QUICPacketTransmitter.h            |   6 +-
 iocore/net/quic/QUICStream.cc                      |   4 +-
 iocore/net/quic/QUICStreamManager.cc               |   5 +-
 iocore/net/quic/QUICTypes.cc                       |  72 +++++
 iocore/net/quic/QUICTypes.h                        |  50 ++--
 iocore/net/quic/test/test_QUICAckFrameCreator.cc   |  16 +-
 iocore/net/quic/test/test_QUICFrame.cc             | 317 +++++++++++----------
 iocore/net/quic/test/test_QUICLossDetector.cc      | 150 ++++++++--
 iocore/net/quic/test/test_QUICPacket.cc            |  43 ++-
 iocore/net/quic/test/test_QUICPacketFactory.cc     |  11 +-
 iocore/net/quic/test/test_QUICTypeUtil.cc          | 107 +++++++
 iocore/net/quic/test/test_QUICVersionNegotiator.cc |   3 +-
 28 files changed, 868 insertions(+), 434 deletions(-)

-- 
To stop receiving notification emails like this one, please contact
['"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>'].

[trafficserver] 06/08: draft-08: Support Variable-Length Integer Encoding

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 7e7e3fcf0d2990170772cb7dd86b3ee79a60cfc2
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Wed Dec 13 10:22:00 2017 +0900

    draft-08: Support Variable-Length Integer Encoding
---
 iocore/net/quic/QUICTypes.cc              |  72 ++++++++++++++++++++
 iocore/net/quic/QUICTypes.h               |  11 ++-
 iocore/net/quic/test/test_QUICTypeUtil.cc | 107 ++++++++++++++++++++++++++++++
 3 files changed, 189 insertions(+), 1 deletion(-)

diff --git a/iocore/net/quic/QUICTypes.cc b/iocore/net/quic/QUICTypes.cc
index 44e89bd..2c21896 100644
--- a/iocore/net/quic/QUICTypes.cc
+++ b/iocore/net/quic/QUICTypes.cc
@@ -167,3 +167,75 @@ QUICError::code()
 {
   return static_cast<uint16_t>(this->trans_error_code);
 }
+
+size_t
+QUICVariableInt::size(const uint8_t *src)
+{
+  return 1 << (src[0] >> 6);
+}
+
+size_t
+QUICVariableInt::size(uint64_t src)
+{
+  uint8_t flag = 0;
+  if (src > 4611686018427387903) {
+    // max usable bits is 62
+    return 0;
+  } else if (src > 1073741823) {
+    flag = 0x03;
+  } else if (src > 16383) {
+    flag = 0x02;
+  } else if (src > 63) {
+    flag = 0x01;
+  } else {
+    flag = 0x00;
+  }
+
+  return 1 << flag;
+}
+
+int
+QUICVariableInt::encode(uint8_t *dst, size_t dst_len, size_t &len, uint64_t src)
+{
+  uint8_t flag = 0;
+  if (src > 4611686018427387903) {
+    // max usable bits is 62
+    return 1;
+  } else if (src > 1073741823) {
+    flag = 0x03;
+  } else if (src > 16383) {
+    flag = 0x02;
+  } else if (src > 63) {
+    flag = 0x01;
+  } else {
+    flag = 0x00;
+  }
+
+  len = 1 << flag;
+  if (len > dst_len) {
+    return 1;
+  }
+
+  size_t dummy = 0;
+  QUICTypeUtil::write_uint_as_nbytes(src, len, dst, &dummy);
+  dst[0] |= (flag << 6);
+
+  return 0;
+}
+
+int
+QUICVariableInt::decode(uint64_t &dst, size_t &len, const uint8_t *src, size_t src_len)
+{
+  len = 1 << (src[0] >> 6);
+  if (src_len < len) {
+    return 1;
+  }
+
+  uint8_t buf[8] = {0};
+  memcpy(buf, src, len);
+  buf[0] &= 0x3f;
+
+  dst = QUICTypeUtil::read_nbytes_as_uint(buf, len);
+
+  return 0;
+}
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 7429009..7d60131 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -51,7 +51,7 @@ ats_unique_buf ats_unique_malloc(size_t size);
 
 using QUICPacketNumber = uint64_t;
 using QUICVersion      = uint32_t;
-using QUICStreamId     = uint32_t;
+using QUICStreamId     = uint64_t;
 using QUICOffset       = uint64_t;
 
 // TODO: Update version number
@@ -274,3 +274,12 @@ public:
 
 private:
 };
+
+class QUICVariableInt
+{
+public:
+  static size_t size(const uint8_t *src);
+  static size_t size(uint64_t src);
+  static int encode(uint8_t *dst, size_t dst_len, size_t &len, uint64_t src);
+  static int decode(uint64_t &dst, size_t &len, const uint8_t *src, size_t src_len);
+};
diff --git a/iocore/net/quic/test/test_QUICTypeUtil.cc b/iocore/net/quic/test/test_QUICTypeUtil.cc
index 1bea4ba..99ae818 100644
--- a/iocore/net/quic/test/test_QUICTypeUtil.cc
+++ b/iocore/net/quic/test/test_QUICTypeUtil.cc
@@ -67,3 +67,110 @@ TEST_CASE("QUICTypeUtil", "[quic]")
   INFO("2 byte to 8 byte");
   CHECK(memcmp(buf, "\x00\x00\x00\x00\x00\x00\x11\xff", 8) == 0);
 }
+
+TEST_CASE("Variable Length - encoding 1", "[quic]")
+{
+  uint8_t dst[8]   = {0};
+  uint64_t src     = 151288809941952652;
+  size_t len       = 0;
+  uint8_t expect[] = {0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c};
+
+  QUICVariableInt::encode(dst, sizeof(dst), len, src);
+
+  CHECK(len == 8);
+  CHECK(memcmp(dst, expect, 8) == 0);
+}
+
+TEST_CASE("Variable Length - encoding 2", "[quic]")
+{
+  uint8_t dst[8]   = {0};
+  uint64_t src     = 494878333;
+  size_t len       = 0;
+  uint8_t expect[] = {0x9d, 0x7f, 0x3e, 0x7d};
+
+  QUICVariableInt::encode(dst, sizeof(dst), len, src);
+
+  CHECK(len == 4);
+  CHECK(memcmp(dst, expect, 4) == 0);
+}
+
+TEST_CASE("Variable Length - encoding 3", "[quic]")
+{
+  uint8_t dst[8]   = {0};
+  uint64_t src     = 15293;
+  size_t len       = 0;
+  uint8_t expect[] = {0x7b, 0xbd};
+
+  QUICVariableInt::encode(dst, sizeof(dst), len, src);
+
+  CHECK(len == 2);
+  CHECK(memcmp(dst, expect, 2) == 0);
+}
+
+TEST_CASE("Variable Length - encoding 4", "[quic]")
+{
+  uint8_t dst[8]   = {0};
+  uint64_t src     = 37;
+  size_t len       = 0;
+  uint8_t expect[] = {0x25};
+
+  QUICVariableInt::encode(dst, sizeof(dst), len, src);
+
+  CHECK(len == 1);
+  CHECK(memcmp(dst, expect, 1) == 0);
+}
+
+TEST_CASE("Variable Length - decoding 1", "[quic]")
+{
+  uint8_t src[] = {0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c};
+  uint64_t dst  = 0;
+  size_t len    = 0;
+  QUICVariableInt::decode(dst, len, src, sizeof(src));
+
+  CHECK(dst == 151288809941952652);
+  CHECK(len == 8);
+}
+
+TEST_CASE("Variable Length - decoding 2", "[quic]")
+{
+  uint8_t src[] = {0x9d, 0x7f, 0x3e, 0x7d, 0x00, 0x00, 0x00, 0x00};
+  uint64_t dst  = 0;
+  size_t len    = 0;
+  QUICVariableInt::decode(dst, len, src, sizeof(src));
+
+  CHECK(dst == 494878333);
+  CHECK(len == 4);
+}
+
+TEST_CASE("Variable Length - decoding 3", "[quic]")
+{
+  uint8_t src[] = {0x7b, 0xbd, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  uint64_t dst  = 0;
+  size_t len    = 0;
+  QUICVariableInt::decode(dst, len, src, sizeof(src));
+
+  CHECK(dst == 15293);
+  CHECK(len == 2);
+}
+
+TEST_CASE("Variable Length - decoding 4", "[quic]")
+{
+  uint8_t src[] = {0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  uint64_t dst  = 0;
+  size_t len    = 0;
+  QUICVariableInt::decode(dst, len, src, sizeof(src));
+
+  CHECK(dst == 37);
+  CHECK(len == 1);
+}
+
+TEST_CASE("Variable Length - decoding 5", "[quic]")
+{
+  uint8_t src[] = {0x40, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+  uint64_t dst  = 0;
+  size_t len    = 0;
+  QUICVariableInt::decode(dst, len, src, sizeof(src));
+
+  CHECK(dst == 37);
+  CHECK(len == 2);
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver] 03/08: Fix QUICPacketLongHeader::store for new long header format

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 ab3a06b8a88880441539457f4fd314f1a0b55ea1
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Tue Dec 12 16:28:11 2017 +0900

    Fix QUICPacketLongHeader::store for new long header format
---
 iocore/net/quic/QUICPacket.cc                  | 14 ++++++++------
 iocore/net/quic/test/test_QUICPacketFactory.cc |  2 +-
 2 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc
index 7bf6e81..01802ba 100644
--- a/iocore/net/quic/QUICPacket.cc
+++ b/iocore/net/quic/QUICPacket.cc
@@ -240,17 +240,18 @@ QUICPacketLongHeader::store(uint8_t *buf, size_t *len) const
   buf[0] = 0x80;
   buf[0] += static_cast<uint8_t>(this->_type);
   *len += 1;
+
   QUICTypeUtil::write_QUICConnectionId(this->_connection_id, 8, buf + *len, &n);
   *len += n;
 
+  QUICTypeUtil::write_QUICVersion(this->_version, buf + *len, &n);
+  *len += n;
+
   QUICPacketNumber dst = 0;
   size_t dst_len       = 4;
   QUICPacket::encode_packet_number(dst, this->_packet_number, dst_len);
   QUICTypeUtil::write_QUICPacketNumber(dst, dst_len, buf + *len, &n);
   *len += n;
-
-  QUICTypeUtil::write_QUICVersion(this->_version, buf + *len, &n);
-  *len += n;
 }
 
 //
@@ -699,9 +700,10 @@ QUICPacketFactory::create_version_negotiation_packet(const QUICPacket *packet_se
     p += n;
   }
 
-  QUICPacketHeader *header = QUICPacketHeader::build(QUICPacketType::VERSION_NEGOTIATION, packet_sent_by_client->connection_id(),
-                                                     packet_sent_by_client->packet_number(), base_packet_number,
-                                                     packet_sent_by_client->version(), std::move(versions), len);
+  QUICPacketHeader *header =
+    QUICPacketHeader::build(QUICPacketType::VERSION_NEGOTIATION, packet_sent_by_client->connection_id(),
+                            packet_sent_by_client->packet_number(), base_packet_number, 0x00, std::move(versions), len);
+
   return QUICPacketFactory::_create_unprotected_packet(header);
 }
 
diff --git a/iocore/net/quic/test/test_QUICPacketFactory.cc b/iocore/net/quic/test/test_QUICPacketFactory.cc
index 9f22800..97d5665 100644
--- a/iocore/net/quic/test/test_QUICPacketFactory.cc
+++ b/iocore/net/quic/test/test_QUICPacketFactory.cc
@@ -35,8 +35,8 @@ TEST_CASE("QUICPacketFactory_Create_VersionNegotiationPacket", "[quic]")
   uint8_t client_initial_packet_header[] = {
     0x82,                                           // Type
     0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Connection id
-    0x00, 0x00, 0x00, 0x00,                         // Packet number
     0xaa, 0xbb, 0xcc, 0xdd,                         // Version
+    0x00, 0x00, 0x00, 0x00,                         // Packet number
   };
   uint8_t client_initial_packet_payload[] = {
     0x00 // Payload

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver] 08/08: draft-08: Support new STREAM frame format

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 25fc8ab030b5af02283fe120a294eff0b58a4f7b
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Wed Dec 13 16:07:35 2017 +0900

    draft-08: Support new STREAM frame format
---
 iocore/net/quic/QUICApplication.cc     |   2 +-
 iocore/net/quic/QUICEchoApp.cc         |   2 +-
 iocore/net/quic/QUICFrame.cc           | 208 ++++++++++++++---------
 iocore/net/quic/QUICFrame.h            |  20 ++-
 iocore/net/quic/QUICStream.cc          |   4 +-
 iocore/net/quic/QUICStreamManager.cc   |   5 +-
 iocore/net/quic/test/test_QUICFrame.cc | 302 ++++++++++++++++++---------------
 7 files changed, 309 insertions(+), 234 deletions(-)

diff --git a/iocore/net/quic/QUICApplication.cc b/iocore/net/quic/QUICApplication.cc
index 83559e6..ef26055 100644
--- a/iocore/net/quic/QUICApplication.cc
+++ b/iocore/net/quic/QUICApplication.cc
@@ -154,7 +154,7 @@ QUICApplication::reenable(QUICStream *stream)
     stream_io->read_reenable();
     stream_io->write_reenable();
   } else {
-    Debug(tag, "Unknown Stream, id: %d", stream->id());
+    Debug(tag, "Unknown Stream, id: %" PRIx64, stream->id());
   }
 
   return;
diff --git a/iocore/net/quic/QUICEchoApp.cc b/iocore/net/quic/QUICEchoApp.cc
index 5fcc4c6..6451dc7 100644
--- a/iocore/net/quic/QUICEchoApp.cc
+++ b/iocore/net/quic/QUICEchoApp.cc
@@ -41,7 +41,7 @@ QUICEchoApp::main_event_handler(int event, Event *data)
   QUICStream *stream      = reinterpret_cast<QUICStream *>(data->cookie);
   QUICStreamIO *stream_io = this->_find_stream_io(stream->id());
   if (stream_io == nullptr) {
-    Debug(tag, "Unknown Stream, id: %d", stream->id());
+    Debug(tag, "Unknown Stream, id: %" PRIx64, stream->id());
     return -1;
   }
 
diff --git a/iocore/net/quic/QUICFrame.cc b/iocore/net/quic/QUICFrame.cc
index 8b2f8ca..db04cb6 100644
--- a/iocore/net/quic/QUICFrame.cc
+++ b/iocore/net/quic/QUICFrame.cc
@@ -90,11 +90,7 @@ QUICStreamFrame::type() const
 size_t
 QUICStreamFrame::size() const
 {
-  if (this->_buf) {
-    return this->_get_data_offset() + this->data_length();
-  } else {
-    return 1 + 4 + 8 + 2 + this->data_length();
-  }
+  return this->_get_data_field_offset() + this->data_length();
 }
 
 void
@@ -106,53 +102,41 @@ QUICStreamFrame::store(uint8_t *buf, size_t *len) const
 void
 QUICStreamFrame::store(uint8_t *buf, size_t *len, bool include_length_field) const
 {
-  size_t n;
-  // Build Frame Type: "11FSSOOD"
+  // Build Frame Type: "0b0010OLF"
   buf[0] = static_cast<uint8_t>(QUICFrameType::STREAM);
   *len   = 1;
 
-  // "F" of "11FSSOOD"
-  if (this->has_fin_flag()) {
-    buf[0] += (0x01 << 5);
-  }
+  // Stream ID (i)
+  size_t stream_id_field_len;
 
-  // "SS" of "11FSSOOD"
-  uint8_t stream_id_width = 0;
-  if (this->_stream_id > 0xFFFFFF) {
-    stream_id_width = 3;
-  } else if (this->_stream_id > 0xFFFF) {
-    stream_id_width = 2;
-  } else if (this->_stream_id > 0xFF) {
-    stream_id_width = 1;
-  } else {
-    stream_id_width = 0;
-  }
-  buf[0] += (stream_id_width << 3);
-  QUICTypeUtil::write_QUICStreamId(this->stream_id(), stream_id_width + 1, buf + *len, &n);
-  *len += n;
-
-  // "OO" of "11FSSOOD"
-  uint8_t offset_width = 0;
-  if (this->offset() > 0xFFFFFFFF) {
-    offset_width = 3;
-  } else if (this->offset() > 0xFFFF) {
-    offset_width = 2;
-  } else if (this->offset() > 0x00) {
-    offset_width = 1;
-  } else {
-    offset_width = 0;
+  // FIXME: check length of buf
+  QUICVariableInt::encode(buf + *len, 8, stream_id_field_len, this->_stream_id);
+  *len += stream_id_field_len;
+
+  // [Offset (i)] "O" of "0b0010OLF"
+  if (this->has_offset_field()) {
+    size_t offset_field_len;
+    // FIXME: check length of buf
+    QUICVariableInt::encode(buf + *len, 8, offset_field_len, this->_offset);
+    *len += offset_field_len;
+    buf[0] += 0x04;
   }
-  buf[0] += (offset_width << 1);
-  QUICTypeUtil::write_QUICOffset(this->offset(), offset_width ? 1 << offset_width : 0, buf + *len, &n);
-  *len += n;
 
-  // "D" of "11FSSOOD"
+  // [Length (i)] "L of "0b0010OLF"
   if (include_length_field) {
+    size_t length_field_len;
+    // FIXME: check length of buf
+    QUICVariableInt::encode(buf + *len, 8, length_field_len, this->_data_len);
+    *len += length_field_len;
+    buf[0] += 0x02;
+  }
+
+  // "F" of "0b0010OLF"
+  if (this->has_fin_flag()) {
     buf[0] += 0x01;
-    QUICTypeUtil::write_uint_as_nbytes(this->data_length(), 2, buf + *len, &n);
-    *len += n;
   }
 
+  // Stream Data (*)
   memcpy(buf + *len, this->data(), this->data_length());
   *len += this->data_length();
 }
@@ -161,7 +145,11 @@ QUICStreamId
 QUICStreamFrame::stream_id() const
 {
   if (this->_buf) {
-    return QUICTypeUtil::read_QUICStreamId(this->_buf + this->_get_stream_id_offset(), this->_get_stream_id_len());
+    uint64_t stream_id;
+    size_t encoded_len;
+    QUICVariableInt::decode(stream_id, encoded_len, this->_buf + this->_get_stream_id_field_offset(),
+                            this->_len - this->_get_stream_id_field_offset());
+    return static_cast<QUICStreamId>(stream_id);
   } else {
     return this->_stream_id;
   }
@@ -171,106 +159,160 @@ QUICOffset
 QUICStreamFrame::offset() const
 {
   if (this->_buf) {
-    return QUICTypeUtil::read_QUICOffset(this->_buf + this->_get_offset_offset(), this->_get_offset_len());
+    if (this->has_offset_field()) {
+      uint64_t offset;
+      size_t encoded_len;
+      QUICVariableInt::decode(offset, encoded_len, this->_buf + this->_get_stream_id_field_offset(),
+                              this->_len - this->_get_stream_id_field_offset());
+      return static_cast<QUICOffset>(offset);
+    } else {
+      return 0;
+    }
   } else {
     return this->_offset;
   }
 }
 
+uint64_t
+QUICStreamFrame::data_length() const
+{
+  if (this->_buf) {
+    if (this->has_length_field()) {
+      uint64_t data_len;
+      size_t encoded_len;
+      QUICVariableInt::decode(data_len, encoded_len, this->_buf + this->_get_length_field_offset(),
+                              this->_len - this->_get_length_field_offset());
+      return data_len;
+    } else {
+      return this->_len - this->_get_data_field_offset();
+    }
+  } else {
+    return this->_data_len;
+  }
+}
+
 const uint8_t *
 QUICStreamFrame::data() const
 {
   if (this->_buf) {
-    return this->_buf + this->_get_data_offset();
+    return this->_buf + this->_get_data_field_offset();
   } else {
     return this->_data.get();
   }
 }
 
-size_t
-QUICStreamFrame::data_length() const
+/**
+ * "O" of "0b00010OLF"
+ */
+bool
+QUICStreamFrame::has_offset_field() const
 {
   if (this->_buf) {
-    if (this->has_data_length_field()) {
-      return QUICTypeUtil::read_nbytes_as_uint(this->_buf + this->_get_offset_offset() + this->_get_offset_len(), 2);
-    } else {
-      return this->_len - this->_get_data_offset();
-    }
+    return (this->_buf[0] & 0x40) != 0;
   } else {
-    return this->_data_len;
+    return this->_offset != 0;
   }
 }
 
 /**
- * "D" of "11FSSOOD"
+ * "L" of "0b00010OLF"
  */
 bool
-QUICStreamFrame::has_data_length_field() const
+QUICStreamFrame::has_length_field() const
 {
-  return (this->_buf[0] & 0x01) != 0;
+  if (this->_buf) {
+    return (this->_buf[0] & 0x02) != 0;
+  } else {
+    // This depends on `include_length_field` arg of QUICStreamFrame::store.
+    // Returning true for just in case.
+    return true;
+  }
 }
 
 /**
- * "F" of "11FSSOOD"
+ * "F" of "0b00010OLF"
  */
 bool
 QUICStreamFrame::has_fin_flag() const
 {
   if (this->_buf) {
-    return (this->_buf[0] & 0x20) != 0;
+    return (this->_buf[0] & 0x01) != 0;
   } else {
     return this->_fin;
   }
 }
 
 size_t
-QUICStreamFrame::_get_stream_id_offset() const
+QUICStreamFrame::_get_stream_id_field_offset() const
 {
   return 1;
 }
 
 size_t
-QUICStreamFrame::_get_offset_offset() const
+QUICStreamFrame::_get_offset_field_offset() const
+{
+  size_t offset_field_offset = this->_get_stream_id_field_offset();
+  offset_field_offset += this->_get_stream_id_field_len();
+
+  return offset_field_offset;
+}
+
+size_t
+QUICStreamFrame::_get_length_field_offset() const
+{
+  size_t length_field_offset = this->_get_stream_id_field_offset();
+  length_field_offset += this->_get_stream_id_field_len();
+  length_field_offset += this->_get_offset_field_len();
+
+  return length_field_offset;
+}
+
+size_t
+QUICStreamFrame::_get_data_field_offset() const
 {
-  return this->_get_stream_id_offset() + this->_get_stream_id_len();
+  size_t data_field_offset = this->_get_stream_id_field_offset();
+  data_field_offset += this->_get_stream_id_field_len();
+  data_field_offset += this->_get_offset_field_len();
+  data_field_offset += this->_get_length_field_len();
+
+  return data_field_offset;
 }
 
 size_t
-QUICStreamFrame::_get_data_offset() const
+QUICStreamFrame::_get_stream_id_field_len() const
 {
   if (this->_buf) {
-    if (this->has_data_length_field()) {
-      return this->_get_offset_offset() + this->_get_offset_len() + 2;
-    } else {
-      return this->_get_offset_offset() + this->_get_offset_len();
-    }
+    return QUICVariableInt::size(this->_buf + this->_get_stream_id_field_offset());
   } else {
-    return 0;
+    return QUICVariableInt::size(this->_stream_id);
   }
 }
 
-/**
- * "SS" of "11FSSOOD"
- * The value 00, 01, 02, and 03 indicate lengths of 8, 16, 24, and 32 bits long respectively.
- */
 size_t
-QUICStreamFrame::_get_stream_id_len() const
+QUICStreamFrame::_get_offset_field_len() const
 {
-  return ((this->_buf[0] & 0x18) >> 3) + 1;
+  if (this->_buf) {
+    if (this->has_offset_field()) {
+      return QUICVariableInt::size(this->_buf + this->_get_offset_field_offset());
+    } else {
+      return 0;
+    }
+  } else {
+    return QUICVariableInt::size(this->_offset);
+  }
 }
 
-/**
- * "OO" of "11FSSOOD"
- * The values 00, 01, 02, and 03 indicate lengths of 0, 16, 32, and 64 bits long respectively.
- */
 size_t
-QUICStreamFrame::_get_offset_len() const
+QUICStreamFrame::_get_length_field_len() const
 {
-  int OO_bits = (this->_buf[0] & 0x06) >> 1;
-  if (OO_bits == 0) {
-    return 0;
+  if (this->_buf) {
+    if (this->has_length_field()) {
+      return QUICVariableInt::size(this->_buf + this->_get_length_field_offset());
+    } else {
+      return 0;
+    }
   } else {
-    return 0x01 << OO_bits;
+    return QUICVariableInt::size(this->_data_len);
   }
 }
 
diff --git a/iocore/net/quic/QUICFrame.h b/iocore/net/quic/QUICFrame.h
index 59fd66d..a4d3b07 100644
--- a/iocore/net/quic/QUICFrame.h
+++ b/iocore/net/quic/QUICFrame.h
@@ -36,7 +36,7 @@ class QUICFrame
 public:
   QUICFrame(const uint8_t *buf, size_t len) : _buf(buf), _len(len){};
   virtual QUICFrameType type() const;
-  virtual size_t size() const = 0;
+  virtual size_t size() const                         = 0;
   virtual void store(uint8_t *buf, size_t *len) const = 0;
   virtual void reset(const uint8_t *buf, size_t len);
   static QUICFrameType type(const uint8_t *buf);
@@ -66,8 +66,9 @@ public:
   QUICStreamId stream_id() const;
   QUICOffset offset() const;
   const uint8_t *data() const;
-  size_t data_length() const;
-  bool has_data_length_field() const;
+  uint64_t data_length() const;
+  bool has_offset_field() const;
+  bool has_length_field() const;
   bool has_fin_flag() const;
 
   LINK(QUICStreamFrame, link);
@@ -78,11 +79,14 @@ private:
   QUICStreamId _stream_id = 0;
   QUICOffset _offset      = 0;
   bool _fin               = false;
-  size_t _get_data_offset() const;
-  size_t _get_stream_id_offset() const;
-  size_t _get_offset_offset() const;
-  size_t _get_stream_id_len() const;
-  size_t _get_offset_len() const;
+  size_t _get_stream_id_field_offset() const;
+  size_t _get_offset_field_offset() const;
+  size_t _get_length_field_offset() const;
+  size_t _get_data_field_offset() const;
+
+  size_t _get_stream_id_field_len() const;
+  size_t _get_offset_field_len() const;
+  size_t _get_length_field_len() const;
 };
 
 //
diff --git a/iocore/net/quic/QUICStream.cc b/iocore/net/quic/QUICStream.cc
index 1ca315e..4dafbf1 100644
--- a/iocore/net/quic/QUICStream.cc
+++ b/iocore/net/quic/QUICStream.cc
@@ -29,10 +29,10 @@
 #include "QUICConfig.h"
 
 #define QUICStreamDebug(fmt, ...)                                                                                       \
-  Debug("quic_stream", "[%" PRIx64 "] [%" PRIx32 "] [%s] " fmt, static_cast<uint64_t>(this->_connection_id), this->_id, \
+  Debug("quic_stream", "[%" PRIx64 "] [%" PRIx64 "] [%s] " fmt, static_cast<uint64_t>(this->_connection_id), this->_id, \
         QUICDebugNames::stream_state(this->_state), ##__VA_ARGS__)
 #define QUICStreamFCDebug(fmt, ...)                                                                                        \
-  Debug("quic_flow_ctrl", "[%" PRIx64 "] [%" PRIx32 "] [%s] " fmt, static_cast<uint64_t>(this->_connection_id), this->_id, \
+  Debug("quic_flow_ctrl", "[%" PRIx64 "] [%" PRIx64 "] [%s] " fmt, static_cast<uint64_t>(this->_connection_id), this->_id, \
         QUICDebugNames::stream_state(this->_state), ##__VA_ARGS__)
 
 QUICStream::~QUICStream()
diff --git a/iocore/net/quic/QUICStreamManager.cc b/iocore/net/quic/QUICStreamManager.cc
index f3b3d94..5223bb4 100644
--- a/iocore/net/quic/QUICStreamManager.cc
+++ b/iocore/net/quic/QUICStreamManager.cc
@@ -40,7 +40,10 @@ std::vector<QUICFrameType>
 QUICStreamManager::interests()
 {
   return {
-    QUICFrameType::STREAM, QUICFrameType::RST_STREAM, QUICFrameType::MAX_STREAM_DATA, QUICFrameType::MAX_STREAM_ID,
+    QUICFrameType::STREAM,
+    QUICFrameType::RST_STREAM,
+    QUICFrameType::MAX_STREAM_DATA,
+    QUICFrameType::MAX_STREAM_ID,
   };
 }
 
diff --git a/iocore/net/quic/test/test_QUICFrame.cc b/iocore/net/quic/test/test_QUICFrame.cc
index fc09cd4..5aed7ba 100644
--- a/iocore/net/quic/test/test_QUICFrame.cc
+++ b/iocore/net/quic/test/test_QUICFrame.cc
@@ -54,30 +54,10 @@ TEST_CASE("QUICFrame Type", "[quic]")
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xff")) == QUICFrameType::UNKNOWN);
 }
 
-TEST_CASE("Construct QUICFrame", "[quic]")
-{
-  uint8_t raw[]          = "foo";
-  ats_unique_buf payload = ats_unique_malloc(sizeof(raw));
-  memcpy(payload.get(), raw, sizeof(raw));
-
-  uint8_t buf[65536];
-  size_t len;
-
-  QUICStreamFrame frame1(std::move(payload), sizeof(raw), 0xffcc9966, 0xffddbb9977553311);
-  frame1.store(buf, &len);
-  CHECK(frame1.type() == QUICFrameType::STREAM);
-  CHECK(frame1.size() == 19);
-  CHECK(frame1.stream_id() == 0xffcc9966);
-  CHECK(frame1.offset() == 0xffddbb9977553311);
-  CHECK(frame1.data_length() == 4);
-  CHECK(memcmp(frame1.data(), "foo\0", 4) == 0);
-  CHECK(frame1.has_fin_flag() == false);
-}
-
 TEST_CASE("Load STREAM Frame 1", "[quic]")
 {
   uint8_t buf1[] = {
-    0xC0,                   // 11FSSOOD
+    0x10,                   // 0b00010OLF (OLF=000)
     0x01,                   // Stream ID
     0x01, 0x02, 0x03, 0x04, // Stream Data
   };
@@ -95,14 +75,14 @@ TEST_CASE("Load STREAM Frame 1", "[quic]")
 TEST_CASE("Load STREAM Frame 2", "[quic]")
 {
   uint8_t buf1[] = {
-    0xC1,                         // 11FSSOOD
+    0x12,                         // 0b00010OLF (OLF=010)
     0x01,                         // Stream ID
-    0x00, 0x05,                   // Data Length
+    0x05,                         // Data Length
     0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
   };
   std::shared_ptr<const QUICFrame> frame1 = QUICFrameFactory::create(buf1, sizeof(buf1));
   CHECK(frame1->type() == QUICFrameType::STREAM);
-  CHECK(frame1->size() == 9);
+  CHECK(frame1->size() == 8);
   std::shared_ptr<const QUICStreamFrame> streamFrame1 = std::dynamic_pointer_cast<const QUICStreamFrame>(frame1);
   CHECK(streamFrame1->stream_id() == 0x01);
   CHECK(streamFrame1->offset() == 0x00);
@@ -113,127 +93,173 @@ TEST_CASE("Load STREAM Frame 2", "[quic]")
 
 TEST_CASE("Store STREAM Frame", "[quic]")
 {
-  uint8_t buf[65535];
-  size_t len;
+  SECTION("8bit stream id, 0bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected1[] = {
+      0x12,                         // 0b00010OLF (OLF=010)
+      0x01,                         // Stream ID
+      0x05,                         // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
+    };
 
-  // 8bit stream id, 0bit offset
-  uint8_t expected1[] = {
-    0xC1,                         // 11FSSOOD
-    0x01,                         // Stream ID
-    0x00, 0x05,                   // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
-  };
+    uint8_t raw1[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload1 = ats_unique_malloc(5);
+    memcpy(payload1.get(), raw1, 5);
 
-  uint8_t raw1[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload1 = ats_unique_malloc(5);
-  memcpy(payload1.get(), raw1, 5);
+    QUICStreamFrame streamFrame1(std::move(payload1), 5, 0x01, 0x00);
+    streamFrame1.store(buf, &len);
+    CHECK(len == 8);
+    CHECK(memcmp(buf, expected1, len) == 0);
+  }
 
-  QUICStreamFrame streamFrame1(std::move(payload1), 5, 0x01, 0x00);
-  streamFrame1.store(buf, &len);
-  CHECK(len == 9);
-  CHECK(memcmp(buf, expected1, len) == 0);
+  SECTION("8bit stream id, 16bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected2[] = {
+      0x16,                         // 0b00010OLF (OLF=110)
+      0x01,                         // Stream ID
+      0x01,                         // Offset
+      0x05,                         // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
+    };
+    uint8_t raw2[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload2 = ats_unique_malloc(5);
+    memcpy(payload2.get(), raw2, 5);
+
+    QUICStreamFrame streamFrame2(std::move(payload2), 5, 0x01, 0x01);
+    streamFrame2.store(buf, &len);
+    CHECK(len == 9);
+    CHECK(memcmp(buf, expected2, len) == 0);
+  }
 
-  // 8bit stream id, 16bit offset
-  uint8_t expected2[] = {
-    0xC3,                         // 11FSSOOD
-    0x01,                         // Stream ID
-    0x00, 0x01,                   // Offset
-    0x00, 0x05,                   // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
-  };
-  uint8_t raw2[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload2 = ats_unique_malloc(5);
-  memcpy(payload2.get(), raw2, 5);
+  SECTION("8bit stream id, 32bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected3[] = {
+      0x16,                         // 0b00010OLF (OLF=110)
+      0x01,                         // Stream ID
+      0x80, 0x01, 0x00, 0x00,       // Offset
+      0x05,                         // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
+    };
+    uint8_t raw3[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload3 = ats_unique_malloc(5);
+    memcpy(payload3.get(), raw3, 5);
+
+    QUICStreamFrame streamFrame3(std::move(payload3), 5, 0x01, 0x010000);
+    streamFrame3.store(buf, &len);
+    CHECK(len == 12);
+    CHECK(memcmp(buf, expected3, len) == 0);
+  }
 
-  QUICStreamFrame streamFrame2(std::move(payload2), 5, 0x01, 0x01);
-  streamFrame2.store(buf, &len);
-  CHECK(len == 11);
-  CHECK(memcmp(buf, expected2, len) == 0);
+  SECTION("8bit stream id, 64bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected4[] = {
+      0x16,                                           // 0b00010OLF (OLF=110)
+      0x01,                                           // Stream ID
+      0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
+      0x05,                                           // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
+    };
+    uint8_t raw4[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload4 = ats_unique_malloc(5);
+    memcpy(payload4.get(), raw4, 5);
+
+    QUICStreamFrame streamFrame4(std::move(payload4), 5, 0x01, 0x0100000000);
+    streamFrame4.store(buf, &len);
+    CHECK(len == 16);
+    CHECK(memcmp(buf, expected4, len) == 0);
+  }
 
-  // 8bit stream id, 32bit offset
-  uint8_t expected3[] = {
-    0xC5,                         // 11FSSOOD
-    0x01,                         // Stream ID
-    0x00, 0x01, 0x00, 0x00,       // Offset
-    0x00, 0x05,                   // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05, // Stream Data
-  };
-  uint8_t raw3[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload3 = ats_unique_malloc(5);
-  memcpy(payload3.get(), raw3, 5);
+  SECTION("16bit stream id, 64bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected5[] = {
+      0x16,                                           // 0b00010OLF (OLF=110)
+      0x41, 0x00,                                     // Stream ID
+      0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
+      0x05,                                           // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
+    };
+    uint8_t raw5[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload5 = ats_unique_malloc(5);
+    memcpy(payload5.get(), raw5, 5);
+
+    QUICStreamFrame streamFrame5(std::move(payload5), 5, 0x0100, 0x0100000000);
+    streamFrame5.store(buf, &len);
+    CHECK(len == 17);
+    CHECK(memcmp(buf, expected5, len) == 0);
+  }
 
-  QUICStreamFrame streamFrame3(std::move(payload3), 5, 0x01, 0x010000);
-  streamFrame3.store(buf, &len);
-  CHECK(len == 13);
-  CHECK(memcmp(buf, expected3, len) == 0);
-
-  // 8bit stream id, 64bit offset
-  uint8_t expected4[] = {
-    0xC7,                                           // 11FSSOOD
-    0x01,                                           // Stream ID
-    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
-    0x00, 0x05,                                     // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
-  };
-  uint8_t raw4[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload4 = ats_unique_malloc(5);
-  memcpy(payload4.get(), raw4, 5);
-
-  QUICStreamFrame streamFrame4(std::move(payload4), 5, 0x01, 0x0100000000);
-  streamFrame4.store(buf, &len);
-  CHECK(len == 17);
-  CHECK(memcmp(buf, expected4, len) == 0);
-
-  // 16bit stream id, 64bit offset
-  uint8_t expected5[] = {
-    0xCF,                                           // 11FSSOOD
-    0x01, 0x00,                                     // Stream ID
-    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
-    0x00, 0x05,                                     // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
-  };
-  uint8_t raw5[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload5 = ats_unique_malloc(5);
-  memcpy(payload5.get(), raw5, 5);
-
-  QUICStreamFrame streamFrame5(std::move(payload5), 5, 0x0100, 0x0100000000);
-  streamFrame5.store(buf, &len);
-  CHECK(len == 18);
-  CHECK(memcmp(buf, expected5, len) == 0);
-
-  // 24bit stream id, 64bit offset
-  uint8_t expected6[] = {
-    0xD7,                                           // 11FSSOOD
-    0x01, 0x00, 0x00,                               // Stream ID
-    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
-    0x00, 0x05,                                     // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
-  };
-  uint8_t raw6[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload6 = ats_unique_malloc(5);
-  memcpy(payload6.get(), raw6, 5);
-
-  QUICStreamFrame streamFrame6(std::move(payload6), 5, 0x010000, 0x0100000000);
-  streamFrame6.store(buf, &len);
-  CHECK(len == 19);
-  CHECK(memcmp(buf, expected6, len) == 0);
-
-  // 32bit stream id, 64bit offset
-  uint8_t expected7[] = {
-    0xDF,                                           // 11FSSOOD
-    0x01, 0x00, 0x00, 0x00,                         // Stream ID
-    0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
-    0x00, 0x05,                                     // Data Length
-    0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
-  };
-  uint8_t raw7[]          = "\x01\x02\x03\x04\x05";
-  ats_unique_buf payload7 = ats_unique_malloc(5);
-  memcpy(payload7.get(), raw7, 5);
-
-  QUICStreamFrame streamFrame7(std::move(payload7), 5, 0x01000000, 0x0100000000);
-  streamFrame7.store(buf, &len);
-  CHECK(len == 20);
-  CHECK(memcmp(buf, expected7, len) == 0);
+  SECTION("24bit stream id, 64bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected6[] = {
+      0x16,                                           // 0b00010OLF (OLF=110)
+      0x80, 0x01, 0x00, 0x00,                         // Stream ID
+      0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
+      0x05,                                           // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
+    };
+    uint8_t raw6[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload6 = ats_unique_malloc(5);
+    memcpy(payload6.get(), raw6, 5);
+
+    QUICStreamFrame streamFrame6(std::move(payload6), 5, 0x010000, 0x0100000000);
+    streamFrame6.store(buf, &len);
+    CHECK(len == 19);
+    CHECK(memcmp(buf, expected6, len) == 0);
+  }
+
+  SECTION("32bit stream id, 64bit offset")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected7[] = {
+      0x16,                                           // 0b00010OLF (OLF=110)
+      0x81, 0x00, 0x00, 0x00,                         // Stream ID
+      0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
+      0x05,                                           // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
+    };
+    uint8_t raw7[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload7 = ats_unique_malloc(5);
+    memcpy(payload7.get(), raw7, 5);
+
+    QUICStreamFrame streamFrame7(std::move(payload7), 5, 0x01000000, 0x0100000000);
+    streamFrame7.store(buf, &len);
+    CHECK(len == 19);
+    CHECK(memcmp(buf, expected7, len) == 0);
+  }
+
+  SECTION("32bit stream id, 64bit offset, FIN bit")
+  {
+    uint8_t buf[32] = {0};
+    size_t len;
+    uint8_t expected[] = {
+      0x17,                                           // 0b00010OLF (OLF=111)
+      0x81, 0x00, 0x00, 0x00,                         // Stream ID
+      0xc0, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // Offset
+      0x05,                                           // Data Length
+      0x01, 0x02, 0x03, 0x04, 0x05,                   // Stream Data
+    };
+    uint8_t raw[]          = "\x01\x02\x03\x04\x05";
+    ats_unique_buf payload = ats_unique_malloc(5);
+    memcpy(payload.get(), raw, 5);
+
+    QUICStreamFrame streamFrame(std::move(payload), 5, 0x01000000, 0x0100000000, true);
+    streamFrame.store(buf, &len);
+    CHECK(len == 19);
+    CHECK(memcmp(buf, expected, len) == 0);
+  }
 }
 
 TEST_CASE("Load Ack Frame 1", "[quic]")

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver] 01/08: draft-08: Support long header packet type & format

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 387788783bf1013b982474ee59ec095345c964dd
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Tue Dec 12 15:55:34 2017 +0900

    draft-08: Support long header packet type & format
---
 iocore/net/QUICNetVConnection.cc                   | 16 ++---
 iocore/net/quic/QUICDebugNames.cc                  | 14 ++--
 iocore/net/quic/QUICHandshake.cc                   |  2 +-
 iocore/net/quic/QUICLossDetector.cc                |  4 +-
 iocore/net/quic/QUICPacket.cc                      | 77 ++++++++++++----------
 iocore/net/quic/QUICPacket.h                       |  8 +--
 iocore/net/quic/QUICTypes.h                        | 20 +++---
 iocore/net/quic/test/test_QUICLossDetector.cc      |  4 +-
 iocore/net/quic/test/test_QUICPacket.cc            | 41 ++++++++----
 iocore/net/quic/test/test_QUICPacketFactory.cc     |  6 +-
 iocore/net/quic/test/test_QUICVersionNegotiator.cc |  3 +-
 11 files changed, 106 insertions(+), 89 deletions(-)

diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc
index 226fcd2..013d1ee 100644
--- a/iocore/net/QUICNetVConnection.cc
+++ b/iocore/net/QUICNetVConnection.cc
@@ -596,10 +596,10 @@ QUICNetVConnection::_state_handshake_process_packet(QUICPacketUPtr packet)
 {
   QUICErrorUPtr error = QUICErrorUPtr(new QUICNoError());
   switch (packet->type()) {
-  case QUICPacketType::CLIENT_INITIAL:
+  case QUICPacketType::INITIAL:
     error = this->_state_handshake_process_initial_client_packet(std::move(packet));
     break;
-  case QUICPacketType::CLIENT_CLEARTEXT:
+  case QUICPacketType::HANDSHAKE:
     error = this->_state_handshake_process_client_cleartext_packet(std::move(packet));
     break;
   case QUICPacketType::ZERO_RTT_PROTECTED:
@@ -700,7 +700,7 @@ QUICNetVConnection::_state_common_receive_packet()
   case QUICPacketType::PROTECTED:
     error = this->_state_connection_established_process_packet(std::move(p));
     break;
-  case QUICPacketType::CLIENT_CLEARTEXT:
+  case QUICPacketType::HANDSHAKE:
     // FIXME Just ignore for now but it has to be acked (GitHub#2609)
     break;
   default:
@@ -857,17 +857,17 @@ QUICNetVConnection::_build_packet(ats_unique_buf buf, size_t len, bool retransmi
   QUICPacketUPtr packet = QUICPacketFactory::create_null_packet();
 
   switch (type) {
-  case QUICPacketType::SERVER_CLEARTEXT:
-    packet = this->_packet_factory.create_server_cleartext_packet(this->_quic_connection_id, this->largest_acked_packet_number(),
-                                                                  std::move(buf), len, retransmittable);
+  case QUICPacketType::HANDSHAKE:
+    packet = this->_packet_factory.create_handshake_packet(this->_quic_connection_id, this->largest_acked_packet_number(),
+                                                           std::move(buf), len, retransmittable);
     break;
   default:
     if (this->_handshake_handler && this->_handshake_handler->is_completed()) {
       packet = this->_packet_factory.create_server_protected_packet(this->_quic_connection_id, this->largest_acked_packet_number(),
                                                                     std::move(buf), len, retransmittable);
     } else {
-      packet = this->_packet_factory.create_server_cleartext_packet(this->_quic_connection_id, this->largest_acked_packet_number(),
-                                                                    std::move(buf), len, retransmittable);
+      packet = this->_packet_factory.create_handshake_packet(this->_quic_connection_id, this->largest_acked_packet_number(),
+                                                             std::move(buf), len, retransmittable);
     }
     break;
   }
diff --git a/iocore/net/quic/QUICDebugNames.cc b/iocore/net/quic/QUICDebugNames.cc
index dd750df..1b794c9 100644
--- a/iocore/net/quic/QUICDebugNames.cc
+++ b/iocore/net/quic/QUICDebugNames.cc
@@ -30,14 +30,12 @@ QUICDebugNames::packet_type(QUICPacketType type)
   switch (type) {
   case QUICPacketType::VERSION_NEGOTIATION:
     return "VERSION_NEGOTIATION";
-  case QUICPacketType::CLIENT_INITIAL:
-    return "CLIENT_INITIAL";
-  case QUICPacketType::SERVER_STATELESS_RETRY:
-    return "SERVER_STATELESS_RETRY";
-  case QUICPacketType::SERVER_CLEARTEXT:
-    return "SERVER_CLEARTEXT";
-  case QUICPacketType::CLIENT_CLEARTEXT:
-    return "CLIENT_CLEARTEXT";
+  case QUICPacketType::INITIAL:
+    return "INITIAL";
+  case QUICPacketType::RETRY:
+    return "RETRY";
+  case QUICPacketType::HANDSHAKE:
+    return "HANDSHAKE";
   case QUICPacketType::ZERO_RTT_PROTECTED:
     return "ZERO_RTT_PROTECTED";
   case QUICPacketType::PROTECTED:
diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc
index 5c262c8..8214a15 100644
--- a/iocore/net/quic/QUICHandshake.cc
+++ b/iocore/net/quic/QUICHandshake.cc
@@ -108,7 +108,7 @@ QUICHandshake::start(const QUICPacket *initial_packet, QUICPacketFactory *packet
 {
   // Negotiate version
   if (this->_version_negotiator->status() == QUICVersionNegotiationStatus::NOT_NEGOTIATED) {
-    if (initial_packet->type() != QUICPacketType::CLIENT_INITIAL) {
+    if (initial_packet->type() != QUICPacketType::HANDSHAKE) {
       return QUICErrorUPtr(new QUICConnectionError(QUICTransErrorCode::PROTOCOL_VIOLATION));
     }
     if (initial_packet->version()) {
diff --git a/iocore/net/quic/QUICLossDetector.cc b/iocore/net/quic/QUICLossDetector.cc
index ec19795..31cae5a 100644
--- a/iocore/net/quic/QUICLossDetector.cc
+++ b/iocore/net/quic/QUICLossDetector.cc
@@ -150,9 +150,9 @@ QUICLossDetector::on_packet_sent(QUICPacketUPtr packet)
 
   bool is_handshake   = false;
   QUICPacketType type = packet->type();
+
   // XXX: Should QUICPacketType::SERVER_STATELESS_RETRY be included?
-  if (type == QUICPacketType::CLIENT_INITIAL || type == QUICPacketType::SERVER_CLEARTEXT ||
-      type == QUICPacketType::CLIENT_CLEARTEXT) {
+  if (type == QUICPacketType::INITIAL || type == QUICPacketType::HANDSHAKE) {
     is_handshake = true;
   }
 
diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc
index 048d3d2..3fbc20f 100644
--- a/iocore/net/quic/QUICPacket.cc
+++ b/iocore/net/quic/QUICPacket.cc
@@ -29,11 +29,15 @@ ClassAllocator<QUICPacket> quicPacketAllocator("quicPacketAllocator");
 ClassAllocator<QUICPacketLongHeader> quicPacketLongHeaderAllocator("quicPacketLongHeaderAllocator");
 ClassAllocator<QUICPacketShortHeader> quicPacketShortHeaderAllocator("quicPacketShortHeaderAllocator");
 
-static constexpr int OFFSET_CONNECTION_ID = 1;
-static constexpr int OFFSET_PACKET_NUMBER = 9;
-static constexpr int OFFSET_VERSION       = 13;
-static constexpr int OFFSET_PAYLOAD       = 17;
-static constexpr int LONGHEADER_LENGTH    = 17;
+static constexpr int LONG_HDR_OFFSET_CONNECTION_ID = 1;
+static constexpr int LONG_HDR_OFFSET_VERSION       = 9;
+static constexpr int LONG_HDR_OFFSET_PACKET_NUMBER = 13;
+static constexpr int LONG_HDR_OFFSET_PAYLOAD       = 17;
+static constexpr int LONG_HDR_LENGTH               = 17;
+
+static constexpr int SHORT_HDR_OFFSET_CONNECTION_ID = 1;
+
+static constexpr int VERSION_NEGOTIATION_PKT_HEADER_LENGTH = 13;
 
 //
 // QUICPacketHeader
@@ -126,11 +130,12 @@ QUICPacketType
 QUICPacketLongHeader::type() const
 {
   if (this->_buf) {
-    int type = this->_buf[0] & 0x7F;
-    if (type < static_cast<int>(QUICPacketType::UNINITIALIZED)) {
-      return static_cast<QUICPacketType>(type);
+    uint8_t type = this->_buf[0] & 0x7F;
+    if (this->version() == 0x00) {
+      return QUICPacketType::VERSION_NEGOTIATION;
     } else {
-      return QUICPacketType::UNINITIALIZED;
+      // any other version-specific type?
+      return static_cast<QUICPacketType>(type);
     }
   } else {
     return this->_type;
@@ -141,7 +146,7 @@ QUICConnectionId
 QUICPacketLongHeader::connection_id() const
 {
   if (this->_buf) {
-    return QUICTypeUtil::read_QUICConnectionId(this->_buf + OFFSET_CONNECTION_ID, 8);
+    return QUICTypeUtil::read_QUICConnectionId(this->_buf + LONG_HDR_OFFSET_CONNECTION_ID, 8);
   } else {
     return this->_connection_id;
   }
@@ -152,8 +157,8 @@ QUICPacketLongHeader::packet_number() const
 {
   if (this->_buf) {
     const uint8_t packet_number_len = 4;
-    QUICPacketNumber src            = QUICTypeUtil::read_QUICPacketNumber(this->_buf + OFFSET_PACKET_NUMBER, packet_number_len);
-    QUICPacketNumber dst            = 0;
+    QUICPacketNumber src = QUICTypeUtil::read_QUICPacketNumber(this->_buf + LONG_HDR_OFFSET_PACKET_NUMBER, packet_number_len);
+    QUICPacketNumber dst = 0;
     QUICPacket::decode_packet_number(dst, src, packet_number_len, this->_base_packet_number);
 
     return dst;
@@ -172,7 +177,7 @@ QUICVersion
 QUICPacketLongHeader::version() const
 {
   if (this->_buf) {
-    return QUICTypeUtil::read_QUICVersion(this->_buf + OFFSET_VERSION);
+    return QUICTypeUtil::read_QUICVersion(this->_buf + LONG_HDR_OFFSET_VERSION);
   } else {
     return this->_version;
   }
@@ -188,7 +193,7 @@ const uint8_t *
 QUICPacketLongHeader::payload() const
 {
   if (this->_buf) {
-    return this->_buf + OFFSET_PAYLOAD;
+    return this->_buf + LONG_HDR_OFFSET_PAYLOAD;
   } else {
     return this->_payload.get();
   }
@@ -220,7 +225,11 @@ QUICPacketLongHeader::key_phase() const
 uint16_t
 QUICPacketLongHeader::size() const
 {
-  return LONGHEADER_LENGTH;
+  if (this->type() == QUICPacketType::VERSION_NEGOTIATION) {
+    return VERSION_NEGOTIATION_PKT_HEADER_LENGTH;
+  } else {
+    return LONG_HDR_LENGTH;
+  }
 }
 
 void
@@ -298,7 +307,7 @@ QUICPacketShortHeader::connection_id() const
 {
   if (this->_buf) {
     ink_release_assert(this->has_connection_id());
-    return QUICTypeUtil::read_QUICConnectionId(this->_buf + OFFSET_CONNECTION_ID, 8);
+    return QUICTypeUtil::read_QUICConnectionId(this->_buf + SHORT_HDR_OFFSET_CONNECTION_ID, 8);
   } else {
     return _connection_id;
   }
@@ -309,9 +318,9 @@ QUICPacketShortHeader::packet_number() const
 {
   if (this->_buf) {
     int n      = this->_packet_number_len();
-    int offset = 1;
+    int offset = SHORT_HDR_OFFSET_CONNECTION_ID;
     if (this->has_connection_id()) {
-      offset = OFFSET_PACKET_NUMBER;
+      offset += 8;
     }
 
     QUICPacketNumber src = QUICTypeUtil::read_QUICPacketNumber(this->_buf + offset, n);
@@ -654,9 +663,8 @@ QUICPacketFactory::create(ats_unique_buf buf, size_t len, QUICPacketNumber base_
       result = QUICPacketCreationResult::NOT_READY;
     }
     break;
-  case QUICPacketType::CLIENT_INITIAL:
-  case QUICPacketType::CLIENT_CLEARTEXT:
-  case QUICPacketType::SERVER_CLEARTEXT:
+  case QUICPacketType::INITIAL:
+  case QUICPacketType::HANDSHAKE:
     if (this->_crypto->decrypt(plain_txt.get(), plain_txt_len, max_plain_txt_len, header->payload(), header->payload_size(),
                                header->packet_number(), header->buf(), header->size(), QUICKeyPhase::CLEARTEXT)) {
       result = QUICPacketCreationResult::SUCCESS;
@@ -698,12 +706,21 @@ QUICPacketFactory::create_version_negotiation_packet(const QUICPacket *packet_se
 }
 
 QUICPacketUPtr
-QUICPacketFactory::create_server_cleartext_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
-                                                  ats_unique_buf payload, size_t len, bool retransmittable)
+QUICPacketFactory::create_initial_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number, QUICVersion version,
+                                         ats_unique_buf payload, size_t len)
+{
+  QUICPacketHeader *header = QUICPacketHeader::build(QUICPacketType::INITIAL, connection_id, this->_packet_number_generator.next(),
+                                                     base_packet_number, version, std::move(payload), len);
+  return this->_create_encrypted_packet(header, true);
+}
+
+QUICPacketUPtr
+QUICPacketFactory::create_handshake_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
+                                           ats_unique_buf payload, size_t len, bool retransmittable)
 {
   QUICPacketHeader *header =
-    QUICPacketHeader::build(QUICPacketType::SERVER_CLEARTEXT, connection_id, this->_packet_number_generator.next(),
-                            base_packet_number, this->_version, std::move(payload), len);
+    QUICPacketHeader::build(QUICPacketType::HANDSHAKE, connection_id, this->_packet_number_generator.next(), base_packet_number,
+                            this->_version, std::move(payload), len);
   return this->_create_encrypted_packet(header, retransmittable);
 }
 
@@ -719,16 +736,6 @@ QUICPacketFactory::create_server_protected_packet(QUICConnectionId connection_id
 }
 
 QUICPacketUPtr
-QUICPacketFactory::create_client_initial_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
-                                                QUICVersion version, ats_unique_buf payload, size_t len)
-{
-  QUICPacketHeader *header =
-    QUICPacketHeader::build(QUICPacketType::CLIENT_INITIAL, connection_id, this->_packet_number_generator.next(),
-                            base_packet_number, version, std::move(payload), len);
-  return this->_create_encrypted_packet(header, true);
-}
-
-QUICPacketUPtr
 QUICPacketFactory::create_stateless_reset_packet(QUICConnectionId connection_id, QUICStatelessResetToken stateless_reset_token)
 {
   std::random_device rnd;
diff --git a/iocore/net/quic/QUICPacket.h b/iocore/net/quic/QUICPacket.h
index 79b82cf..5f5d4f7 100644
--- a/iocore/net/quic/QUICPacket.h
+++ b/iocore/net/quic/QUICPacket.h
@@ -295,12 +295,12 @@ public:
 
   QUICPacketUPtr create(ats_unique_buf buf, size_t len, QUICPacketNumber base_packet_number, QUICPacketCreationResult &result);
   QUICPacketUPtr create_version_negotiation_packet(const QUICPacket *packet_sent_by_client, QUICPacketNumber base_packet_number);
-  QUICPacketUPtr create_server_cleartext_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
-                                                ats_unique_buf payload, size_t len, bool retransmittable);
+  QUICPacketUPtr create_initial_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number, QUICVersion version,
+                                       ats_unique_buf payload, size_t len);
+  QUICPacketUPtr create_handshake_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
+                                         ats_unique_buf payload, size_t len, bool retransmittable);
   QUICPacketUPtr create_server_protected_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
                                                 ats_unique_buf payload, size_t len, bool retransmittable);
-  QUICPacketUPtr create_client_initial_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number,
-                                              QUICVersion version, ats_unique_buf payload, size_t len);
   static QUICPacketUPtr create_stateless_reset_packet(QUICConnectionId connection_id,
                                                       QUICStatelessResetToken stateless_reset_token);
   void set_version(QUICVersion negotiated_version);
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 6757d70..09557e8 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -62,16 +62,16 @@ constexpr QUICVersion QUIC_SUPPORTED_VERSIONS[] = {
 };
 constexpr QUICStreamId STREAM_ID_FOR_HANDSHAKE = 0;
 
-enum class QUICPacketType : int {
-  VERSION_NEGOTIATION = 1,
-  CLIENT_INITIAL,
-  SERVER_STATELESS_RETRY,
-  SERVER_CLEARTEXT,
-  CLIENT_CLEARTEXT,
-  ZERO_RTT_PROTECTED,
-  PROTECTED,       // Not on the spec. but just for convenience
-  STATELESS_RESET, // Not on the spec. but just for convenience
-  UNINITIALIZED,   // Not on the spec. but just for convenience
+// Devide to QUICPacketType and QUICPacketLongHeaderType ?
+enum class QUICPacketType : uint8_t {
+  VERSION_NEGOTIATION = 0,
+  PROTECTED,                 // Not on the spec. but just for convenience // should be short header
+  STATELESS_RESET,           // Not on the spec. but just for convenience
+  INITIAL            = 0x7F, // draft-08 version-specific type
+  RETRY              = 0x7E, // draft-08 version-specific type
+  HANDSHAKE          = 0x7D, // draft-08 version-specific type
+  ZERO_RTT_PROTECTED = 0x7C, // draft-08 version-specific type
+  UNINITIALIZED      = 0xFF, // Not on the spec. but just for convenience
 };
 
 // To detect length of Packet Number
diff --git a/iocore/net/quic/test/test_QUICLossDetector.cc b/iocore/net/quic/test/test_QUICLossDetector.cc
index 4284182..af39c41 100644
--- a/iocore/net/quic/test/test_QUICLossDetector.cc
+++ b/iocore/net/quic/test/test_QUICLossDetector.cc
@@ -40,8 +40,8 @@ TEST_CASE("QUICLossDetector_Loss_in_Handshake", "[quic]")
   ats_unique_buf payload = ats_unique_malloc(sizeof(raw));
   memcpy(payload.get(), raw, sizeof(raw));
 
-  QUICPacketHeader *header = QUICPacketHeader::build(QUICPacketType::SERVER_CLEARTEXT, 0xffddbb9977553311ULL, 0x00000001, 0,
-                                                     0x00112233, std::move(payload), 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));
diff --git a/iocore/net/quic/test/test_QUICPacket.cc b/iocore/net/quic/test/test_QUICPacket.cc
index 8a39c57..ee25cb0 100644
--- a/iocore/net/quic/test/test_QUICPacket.cc
+++ b/iocore/net/quic/test/test_QUICPacket.cc
@@ -27,20 +27,41 @@
 
 TEST_CASE("QUICPacketHeader", "[quic]")
 {
+  SECTION("Long Header (load) Version Negotiation Packet")
+  {
+    const uint8_t input[] = {
+      0x80,                                           // Long header, Type: NONE
+      0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Connection ID
+      0x00, 0x00, 0x00, 0x00,                         // Version
+      0x00, 0x00, 0x00, 0x08,                         // Supported Version 1
+      0x00, 0x00, 0x00, 0x09,                         // Supported Version 1
+    };
+
+    QUICPacketHeader *header = QUICPacketHeader::load(input, sizeof(input), 0);
+    CHECK(header->size() == 13);
+    CHECK(header->packet_size() == 21);
+    CHECK(header->type() == QUICPacketType::VERSION_NEGOTIATION);
+    CHECK(header->has_connection_id() == true);
+    CHECK(header->connection_id() == 0x0102030405060708);
+    CHECK(header->has_version() == true);
+    CHECK(header->version() == 0x00000000);
+    CHECK(header->has_key_phase() == false);
+  }
+
   SECTION("Long Header (load)")
   {
     const uint8_t input[] = {
-      0x81,                                           // Long header, Type
+      0xFF,                                           // Long header, Type: INITIAL
       0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Connection ID
-      0x12, 0x34, 0x56, 0x78,                         // Packet number
       0x11, 0x22, 0x33, 0x44,                         // Version
+      0x12, 0x34, 0x56, 0x78,                         // Packet number
       0xff, 0xff,                                     // Payload (dummy)
     };
 
     QUICPacketHeader *header = QUICPacketHeader::load(input, sizeof(input), 0);
     CHECK(header->size() == 17);
     CHECK(header->packet_size() == 19);
-    CHECK(header->type() == QUICPacketType::VERSION_NEGOTIATION);
+    CHECK(header->type() == QUICPacketType::INITIAL);
     CHECK(header->has_connection_id() == true);
     CHECK(header->connection_id() == 0x0102030405060708);
     CHECK(header->packet_number() == 0x12345678);
@@ -55,13 +76,13 @@ TEST_CASE("QUICPacketHeader", "[quic]")
     ats_unique_buf payload   = ats_unique_malloc(sizeof(expected));
     memcpy(payload.get(), expected, sizeof(expected));
 
-    QUICPacketHeader *header = QUICPacketHeader::build(QUICPacketType::CLIENT_INITIAL, 0x0102030405060708, 0x12345678, 0,
-                                                       0xa0a0a0a0, std::move(payload), 32);
+    QUICPacketHeader *header =
+      QUICPacketHeader::build(QUICPacketType::INITIAL, 0x0102030405060708, 0x12345678, 0, 0xa0a0a0a0, std::move(payload), 32);
 
     CHECK(header->size() == 17);
     CHECK(header->has_key_phase() == false);
     CHECK(header->packet_size() == 0);
-    CHECK(header->type() == QUICPacketType::CLIENT_INITIAL);
+    CHECK(header->type() == QUICPacketType::INITIAL);
     CHECK(header->has_connection_id() == true);
     CHECK(header->connection_id() == 0x0102030405060708);
     CHECK(header->packet_number() == 0x12345678);
@@ -110,14 +131,6 @@ TEST_CASE("QUICPacketHeader", "[quic]")
   }
 }
 
-TEST_CASE("Loading Unknown Packet", "[quic]")
-{
-  const uint8_t buf[]      = {0xff};
-  QUICPacketHeader *header = QUICPacketHeader::load(buf, sizeof(buf), 0);
-
-  CHECK(header->type() == QUICPacketType::UNINITIALIZED);
-}
-
 TEST_CASE("Encoded Packet Number Length", "[quic]")
 {
   QUICPacketNumber base = 0x6afa2f;
diff --git a/iocore/net/quic/test/test_QUICPacketFactory.cc b/iocore/net/quic/test/test_QUICPacketFactory.cc
index f5fcf15..9f22800 100644
--- a/iocore/net/quic/test/test_QUICPacketFactory.cc
+++ b/iocore/net/quic/test/test_QUICPacketFactory.cc
@@ -53,7 +53,7 @@ TEST_CASE("QUICPacketFactory_Create_VersionNegotiationPacket", "[quic]")
   CHECK(memcmp(packet->payload(), "\xff\x00\x00\x07", 4) == 0);
 }
 
-TEST_CASE("QUICPacketFactory_Create_ServerCleartextPacket", "[quic]")
+TEST_CASE("QUICPacketFactory_Create_Handshake", "[quic]")
 {
   QUICPacketFactory factory;
   MockQUICCrypto crypto;
@@ -64,8 +64,8 @@ TEST_CASE("QUICPacketFactory_Create_ServerCleartextPacket", "[quic]")
   ats_unique_buf payload = ats_unique_malloc(sizeof(raw));
   memcpy(payload.get(), raw, sizeof(raw));
 
-  QUICPacketUPtr packet = factory.create_server_cleartext_packet(0x01020304, 0, std::move(payload), sizeof(raw), true);
-  CHECK(packet->type() == QUICPacketType::SERVER_CLEARTEXT);
+  QUICPacketUPtr packet = factory.create_handshake_packet(0x01020304, 0, std::move(payload), sizeof(raw), true);
+  CHECK(packet->type() == QUICPacketType::HANDSHAKE);
   CHECK(packet->connection_id() == 0x01020304);
   CHECK(memcmp(packet->payload(), raw, sizeof(raw)) == 0);
   CHECK((packet->packet_number() & 0xFFFFFFFF80000000) == 0);
diff --git a/iocore/net/quic/test/test_QUICVersionNegotiator.cc b/iocore/net/quic/test/test_QUICVersionNegotiator.cc
index c8c0a93..c4b3444 100644
--- a/iocore/net/quic/test/test_QUICVersionNegotiator.cc
+++ b/iocore/net/quic/test/test_QUICVersionNegotiator.cc
@@ -37,8 +37,7 @@ TEST_CASE("QUICVersionNegotiator_Normal", "[quic]")
   CHECK(vn.status() == QUICVersionNegotiationStatus::NOT_NEGOTIATED);
 
   // Negotiate version
-  QUICPacketUPtr initial_packet =
-    packet_factory.create_client_initial_packet({}, 0, QUIC_SUPPORTED_VERSIONS[0], ats_unique_malloc(0), 0);
+  QUICPacketUPtr initial_packet = packet_factory.create_initial_packet({}, 0, QUIC_SUPPORTED_VERSIONS[0], ats_unique_malloc(0), 0);
   vn.negotiate(initial_packet.get());
   CHECK(vn.status() == QUICVersionNegotiationStatus::NEGOTIATED);
 

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver] 02/08: draft-08: Support short header packet type & format

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 624c5c7e3274717667db4faf796867e8bc89d1ce
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Tue Dec 12 16:08:08 2017 +0900

    draft-08: Support short header packet type & format
---
 iocore/net/quic/QUICPacket.cc           | 2 +-
 iocore/net/quic/QUICTypes.h             | 8 ++++----
 iocore/net/quic/test/test_QUICPacket.cc | 2 +-
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc
index 3fbc20f..7bf6e81 100644
--- a/iocore/net/quic/QUICPacket.cc
+++ b/iocore/net/quic/QUICPacket.cc
@@ -386,7 +386,7 @@ bool
 QUICPacketShortHeader::has_connection_id() const
 {
   if (this->_buf) {
-    return (this->_buf[0] & 0x40) != 0;
+    return (this->_buf[0] & 0x40) == 0;
   } else {
     return this->_has_connection_id;
   }
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 09557e8..130bbd6 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -76,10 +76,10 @@ enum class QUICPacketType : uint8_t {
 
 // To detect length of Packet Number
 enum class QUICPacketShortHeaderType : int {
-  ONE = 1,
-  TWO,
-  THREE,
-  UNINITIALIZED,
+  ONE           = 0x1F,
+  TWO           = 0x1E,
+  THREE         = 0x1D,
+  UNINITIALIZED = 0x1C,
 };
 
 // XXX If you add or remove QUICFrameType, you might also need to change QUICFrame::type(const uint8_t *)
diff --git a/iocore/net/quic/test/test_QUICPacket.cc b/iocore/net/quic/test/test_QUICPacket.cc
index ee25cb0..e4877dd 100644
--- a/iocore/net/quic/test/test_QUICPacket.cc
+++ b/iocore/net/quic/test/test_QUICPacket.cc
@@ -93,7 +93,7 @@ TEST_CASE("QUICPacketHeader", "[quic]")
   SECTION("Short Header (load)")
   {
     const uint8_t input[] = {
-      0x43,                                           // Short header, with Connection ID, KeyPhse 0, Type
+      0x1D,                                           // Short header with (C=0, K=0, Type=0x1D)
       0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // Connection ID
       0x12, 0x34, 0x56, 0x78,                         // Packet number
       0xff, 0xff,                                     // Payload (dummy)

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver] 04/08: draft-08: Bump version

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 c90274a75db135e2d420e457ed262cadd69954f2
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Tue Dec 12 16:28:27 2017 +0900

    draft-08: Bump version
---
 iocore/net/quic/QUICTypes.h                    | 4 ++--
 iocore/net/quic/test/test_QUICPacketFactory.cc | 3 ++-
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 130bbd6..7429009 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -55,10 +55,10 @@ using QUICStreamId     = uint32_t;
 using QUICOffset       = uint64_t;
 
 // TODO: Update version number
-// Note: You also need to update tests for VersionNegotiationPacket, if you change the number of versions
+// Note: You also need to update tests for VersionNegotiationPacket creation, if you change the number of versions
 // Prefix for drafts (0xff000000) + draft number
 constexpr QUICVersion QUIC_SUPPORTED_VERSIONS[] = {
-  0xff000007,
+  0xff000008,
 };
 constexpr QUICStreamId STREAM_ID_FOR_HANDSHAKE = 0;
 
diff --git a/iocore/net/quic/test/test_QUICPacketFactory.cc b/iocore/net/quic/test/test_QUICPacketFactory.cc
index 97d5665..db29759 100644
--- a/iocore/net/quic/test/test_QUICPacketFactory.cc
+++ b/iocore/net/quic/test/test_QUICPacketFactory.cc
@@ -50,7 +50,8 @@ TEST_CASE("QUICPacketFactory_Create_VersionNegotiationPacket", "[quic]")
   CHECK(packet->type() == QUICPacketType::VERSION_NEGOTIATION);
   CHECK(packet->connection_id() == client_initial_packet.connection_id());
   CHECK(packet->packet_number() == client_initial_packet.packet_number());
-  CHECK(memcmp(packet->payload(), "\xff\x00\x00\x07", 4) == 0);
+  CHECK(packet->version() == 0x00);
+  CHECK(memcmp(packet->payload(), "\xff\x00\x00\x08", 4) == 0);
 }
 
 TEST_CASE("QUICPacketFactory_Create_Handshake", "[quic]")

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.

[trafficserver] 05/08: Parse and create ack block in draft-08 way

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 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 &current_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>.

[trafficserver] 07/08: draft-08: Adjust frame types

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 3d3b174fd8579feb7d5eaa12d927d16861458b85
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Wed Dec 13 10:56:10 2017 +0900

    draft-08: Adjust frame types
---
 iocore/net/quic/QUICFrame.cc           | 12 ++++++------
 iocore/net/quic/QUICTypes.h            |  7 ++++---
 iocore/net/quic/test/test_QUICFrame.cc | 15 ++++++++-------
 3 files changed, 18 insertions(+), 16 deletions(-)

diff --git a/iocore/net/quic/QUICFrame.cc b/iocore/net/quic/QUICFrame.cc
index 12b09f7..8b2f8ca 100644
--- a/iocore/net/quic/QUICFrame.cc
+++ b/iocore/net/quic/QUICFrame.cc
@@ -50,11 +50,11 @@ QUICFrame::type() const
 QUICFrameType
 QUICFrame::type(const uint8_t *buf)
 {
-  if (buf[0] >= static_cast<uint8_t>(QUICFrameType::STREAM)) {
+  if (buf[0] >= static_cast<uint8_t>(QUICFrameType::UNKNOWN)) {
+    return QUICFrameType::UNKNOWN;
+  } else if (buf[0] >= static_cast<uint8_t>(QUICFrameType::STREAM)) {
     return QUICFrameType::STREAM;
-  } else if (buf[0] >= static_cast<uint8_t>(QUICFrameType::ACK)) {
-    return QUICFrameType::ACK;
-  } else if (buf[0] > static_cast<uint8_t>(QUICFrameType::STOP_SENDING)) {
+  } else if (buf[0] > static_cast<uint8_t>(QUICFrameType::ACK)) {
     return QUICFrameType::UNKNOWN;
   } else {
     return static_cast<QUICFrameType>(buf[0]);
@@ -439,7 +439,7 @@ QUICAckFrame::_get_largest_acknowledged_length() const
    * 1 -> 2 byte
    * 2 -> 4 byte
    * 3 -> 8 byte
-  */
+   */
   int n = (this->_buf[0] & 0x0c) >> 2;
   return 0x01 << n;
 }
@@ -465,7 +465,7 @@ QUICAckFrame::_get_ack_block_length() const
    * 1 -> 2 byte
    * 2 -> 4 byte
    * 3 -> 8 byte
-  */
+   */
   int n = this->_buf[0] & 0x03;
   return 0x01 << n;
 }
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 7d60131..9a6121a 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -97,9 +97,10 @@ enum class QUICFrameType : int {
   STREAM_ID_NEEDED,
   NEW_CONNECTION_ID,
   STOP_SENDING,
-  ACK     = 0xA0,
-  STREAM  = 0xC0,
-  UNKNOWN = 0x100,
+  PONG,
+  ACK,
+  STREAM  = 0x10, // 0x10 - 0x17
+  UNKNOWN = 0x18,
 };
 
 enum class QUICVersionNegotiationStatus {
diff --git a/iocore/net/quic/test/test_QUICFrame.cc b/iocore/net/quic/test/test_QUICFrame.cc
index 3489746..fc09cd4 100644
--- a/iocore/net/quic/test/test_QUICFrame.cc
+++ b/iocore/net/quic/test/test_QUICFrame.cc
@@ -42,15 +42,16 @@ TEST_CASE("QUICFrame Type", "[quic]")
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0a")) == QUICFrameType::STREAM_ID_NEEDED);
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0b")) == QUICFrameType::NEW_CONNECTION_ID);
   CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0c")) == QUICFrameType::STOP_SENDING);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0d")) == QUICFrameType::PONG);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0e")) == QUICFrameType::ACK);
   // Undefined ragne
-  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0d")) == QUICFrameType::UNKNOWN);
-  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x9f")) == QUICFrameType::UNKNOWN);
-  // Range of ACK
-  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xa0")) == QUICFrameType::ACK);
-  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xbf")) == QUICFrameType::ACK);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x0f")) == QUICFrameType::UNKNOWN);
   // Range of STREAM
-  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xc0")) == QUICFrameType::STREAM);
-  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xff")) == QUICFrameType::STREAM);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x10")) == QUICFrameType::STREAM);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x17")) == QUICFrameType::STREAM);
+  // Undefined ragne
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\x18")) == QUICFrameType::UNKNOWN);
+  CHECK(QUICFrame::type(reinterpret_cast<const uint8_t *>("\xff")) == QUICFrameType::UNKNOWN);
 }
 
 TEST_CASE("Construct QUICFrame", "[quic]")

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.