This is an automated email from the ASF dual-hosted git repository.

scw00 pushed a commit to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/quic-latest by this push:
     new 4180a95  QUIC: Uses unidirectional stream to send HTTP3 SETTINGS frames
4180a95 is described below

commit 4180a956490350c9fb4ab2a9f07224b989cc1a59
Author: scw00 <sc...@apache.org>
AuthorDate: Wed Apr 10 06:50:29 2019 +0000

    QUIC: Uses unidirectional stream to send HTTP3 SETTINGS frames
---
 iocore/eventsystem/I_Thread.h              |  2 +
 iocore/net/quic/Makefile.am                |  3 +-
 iocore/net/quic/QUICApplication.cc         | 17 +++++-
 iocore/net/quic/QUICBidirectionalStream.h  |  2 +
 iocore/net/quic/QUICStream.cc              |  8 ++-
 iocore/net/quic/QUICStream.h               |  1 +
 iocore/net/quic/QUICStreamFactory.cc       | 84 ++++++++++++++++++++++++++++++
 iocore/net/quic/QUICStreamFactory.h        | 46 ++++++++++++++++
 iocore/net/quic/QUICStreamManager.cc       | 15 +++---
 iocore/net/quic/QUICStreamManager.h        |  9 ++--
 iocore/net/quic/QUICTypes.cc               | 22 ++++++++
 iocore/net/quic/QUICTypes.h                | 12 +++++
 iocore/net/quic/QUICUnidirectionalStream.h |  5 ++
 13 files changed, 209 insertions(+), 17 deletions(-)

diff --git a/iocore/eventsystem/I_Thread.h b/iocore/eventsystem/I_Thread.h
index 8691206..8153acf 100644
--- a/iocore/eventsystem/I_Thread.h
+++ b/iocore/eventsystem/I_Thread.h
@@ -125,6 +125,8 @@ public:
   ProxyAllocator quicClientSessionAllocator;
   ProxyAllocator quicHandshakeAllocator;
   ProxyAllocator quicBidiStreamAllocator;
+  ProxyAllocator quicSendStreamAllocator;
+  ProxyAllocator quicReceiveStreamAllocator;
   ProxyAllocator quicStreamManagerAllocator;
   ProxyAllocator httpServerSessionAllocator;
   ProxyAllocator hdrHeapAllocator;
diff --git a/iocore/net/quic/Makefile.am b/iocore/net/quic/Makefile.am
index 4a80697..9fd6b27 100644
--- a/iocore/net/quic/Makefile.am
+++ b/iocore/net/quic/Makefile.am
@@ -89,7 +89,8 @@ libquic_a_SOURCES = \
   QUICAddrVerifyState.cc \
   QUICBidirectionalStream.cc \
   QUICCryptoStream.cc \
-  QUICUnidirectionalStream.cc
+  QUICUnidirectionalStream.cc \
+  QUICStreamFactory.cc
 
 #
 # Check Programs
diff --git a/iocore/net/quic/QUICApplication.cc 
b/iocore/net/quic/QUICApplication.cc
index 9b02b8c..9039b99 100644
--- a/iocore/net/quic/QUICApplication.cc
+++ b/iocore/net/quic/QUICApplication.cc
@@ -42,8 +42,21 @@ QUICStreamIO::QUICStreamIO(QUICApplication *app, 
QUICStreamVConnection *stream_v
   this->_read_buffer_reader  = this->_read_buffer->alloc_reader();
   this->_write_buffer_reader = this->_write_buffer->alloc_reader();
 
-  this->_read_vio  = stream_vc->do_io_read(app, INT64_MAX, this->_read_buffer);
-  this->_write_vio = stream_vc->do_io_write(app, INT64_MAX, 
this->_write_buffer_reader);
+  switch (stream_vc->direction()) {
+  case QUICStreamDirection::BIDIRECTIONAL:
+    this->_read_vio  = stream_vc->do_io_read(app, INT64_MAX, 
this->_read_buffer);
+    this->_write_vio = stream_vc->do_io_write(app, INT64_MAX, 
this->_write_buffer_reader);
+    break;
+  case QUICStreamDirection::SEND:
+    this->_write_vio = stream_vc->do_io_write(app, INT64_MAX, 
this->_write_buffer_reader);
+    break;
+  case QUICStreamDirection::RECEIVE:
+    this->_read_vio = stream_vc->do_io_read(app, INT64_MAX, 
this->_read_buffer);
+    break;
+  default:
+    ink_assert(false);
+    break;
+  }
 }
 
 QUICStreamIO::~QUICStreamIO()
diff --git a/iocore/net/quic/QUICBidirectionalStream.h 
b/iocore/net/quic/QUICBidirectionalStream.h
index b756f21..ed583bd 100644
--- a/iocore/net/quic/QUICBidirectionalStream.h
+++ b/iocore/net/quic/QUICBidirectionalStream.h
@@ -38,6 +38,8 @@ public:
   {
   }
 
+  ~QUICBidirectionalStream() {}
+
   int state_stream_open(int event, void *data);
   int state_stream_closed(int event, void *data);
 
diff --git a/iocore/net/quic/QUICStream.cc b/iocore/net/quic/QUICStream.cc
index 3c98ef4..334b9f4 100644
--- a/iocore/net/quic/QUICStream.cc
+++ b/iocore/net/quic/QUICStream.cc
@@ -37,6 +37,12 @@ QUICStream::id() const
   return this->_id;
 }
 
+QUICStreamDirection
+QUICStream::direction() const
+{
+  return QUICTypeUtil::detect_stream_direction(this->_id, 
this->_connection_info->direction());
+}
+
 const QUICConnectionInfoProvider *
 QUICStream::connection_info() const
 {
@@ -46,7 +52,7 @@ QUICStream::connection_info() const
 bool
 QUICStream::is_bidirectional() const
 {
-  return (this->_id & 0x03) < 0x02;
+  return ((this->_id & 0x03) < 0x02);
 }
 
 QUICOffset
diff --git a/iocore/net/quic/QUICStream.h b/iocore/net/quic/QUICStream.h
index fda00bf..bff660a 100644
--- a/iocore/net/quic/QUICStream.h
+++ b/iocore/net/quic/QUICStream.h
@@ -49,6 +49,7 @@ public:
   virtual ~QUICStream();
 
   QUICStreamId id() const;
+  QUICStreamDirection direction() const;
   const QUICConnectionInfoProvider *connection_info() const;
   bool is_bidirectional() const;
   QUICOffset final_offset() const;
diff --git a/iocore/net/quic/QUICStreamFactory.cc 
b/iocore/net/quic/QUICStreamFactory.cc
new file mode 100644
index 0000000..9762895
--- /dev/null
+++ b/iocore/net/quic/QUICStreamFactory.cc
@@ -0,0 +1,84 @@
+/** @file
+ *
+ *  A brief file description
+ *
+ *  @section license License
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include "QUICStream.h"
+#include "QUICBidirectionalStream.h"
+#include "QUICUnidirectionalStream.h"
+#include "QUICStreamFactory.h"
+
+ClassAllocator<QUICBidirectionalStream> 
quicBidiStreamAllocator("quicBidiStreamAllocator");
+ClassAllocator<QUICSendStream> 
quicSendStreamAllocator("quicSendStreamAllocator");
+ClassAllocator<QUICReceiveStream> 
quicReceiveStreamAllocator("quicReceiveStreamAllocator");
+
+QUICStreamVConnection *
+QUICStreamFactory::create(QUICStreamId sid, uint64_t local_max_stream_data, 
uint64_t remote_max_stream_data)
+{
+  QUICStreamVConnection *stream = nullptr;
+  switch (QUICTypeUtil::detect_stream_direction(sid, 
this->_info->direction())) {
+  case QUICStreamDirection::BIDIRECTIONAL:
+    // TODO Free the stream somewhere
+    stream = THREAD_ALLOC(quicBidiStreamAllocator, this_ethread());
+    new (stream) QUICBidirectionalStream(this->_rtt_provider, this->_info, 
sid, local_max_stream_data, remote_max_stream_data);
+    break;
+  case QUICStreamDirection::SEND:
+    // TODO Free the stream somewhere
+    stream = THREAD_ALLOC(quicSendStreamAllocator, this_ethread());
+    new (stream) QUICSendStream(this->_info, sid, remote_max_stream_data);
+    break;
+  case QUICStreamDirection::RECEIVE:
+    // server side
+    // TODO Free the stream somewhere
+    stream = THREAD_ALLOC(quicReceiveStreamAllocator, this_ethread());
+    new (stream) QUICReceiveStream(this->_rtt_provider, this->_info, sid, 
local_max_stream_data);
+    break;
+  default:
+    ink_assert(false);
+    break;
+  }
+
+  return stream;
+}
+
+void
+QUICStreamFactory::delete_stream(QUICStreamVConnection *stream)
+{
+  if (!stream) {
+    return;
+  }
+
+  stream->~QUICStreamVConnection();
+  switch (stream->direction()) {
+  case QUICStreamDirection::BIDIRECTIONAL:
+    THREAD_FREE(static_cast<QUICBidirectionalStream *>(stream), 
quicBidiStreamAllocator, this_thread());
+    break;
+  case QUICStreamDirection::SEND:
+    THREAD_FREE(static_cast<QUICSendStream *>(stream), 
quicSendStreamAllocator, this_thread());
+    break;
+  case QUICStreamDirection::RECEIVE:
+    THREAD_FREE(static_cast<QUICReceiveStream *>(stream), 
quicReceiveStreamAllocator, this_thread());
+    break;
+  default:
+    ink_assert(false);
+    break;
+  }
+}
diff --git a/iocore/net/quic/QUICStreamFactory.h 
b/iocore/net/quic/QUICStreamFactory.h
new file mode 100644
index 0000000..fd497bf
--- /dev/null
+++ b/iocore/net/quic/QUICStreamFactory.h
@@ -0,0 +1,46 @@
+/** @file
+ *
+ *  A brief file description
+ *
+ *  @section license License
+ *
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#pragma once
+
+#include "QUICTypes.h"
+
+class QUICStreamVConnection;
+
+// PS: this class function should not static because of  THREAD_ALLOC and 
THREAD_FREE
+class QUICStreamFactory
+{
+public:
+  QUICStreamFactory(QUICRTTProvider *rtt_provider, QUICConnectionInfoProvider 
*info) : _rtt_provider(rtt_provider), _info(info) {}
+  ~QUICStreamFactory() {}
+
+  // create a bidistream, send only stream or receive only stream
+  QUICStreamVConnection *create(QUICStreamId sid, uint64_t 
recv_max_stream_data, uint64_t send_max_stream_data);
+
+  // delete stream by stream type
+  void delete_stream(QUICStreamVConnection *stream);
+
+private:
+  QUICRTTProvider *_rtt_provider    = nullptr;
+  QUICConnectionInfoProvider *_info = nullptr;
+};
diff --git a/iocore/net/quic/QUICStreamManager.cc 
b/iocore/net/quic/QUICStreamManager.cc
index a4d3188..22e6c2f 100644
--- a/iocore/net/quic/QUICStreamManager.cc
+++ b/iocore/net/quic/QUICStreamManager.cc
@@ -30,10 +30,9 @@ static constexpr char tag[]                     = 
"quic_stream_manager";
 static constexpr QUICStreamId QUIC_STREAM_TYPES = 4;
 
 ClassAllocator<QUICStreamManager> 
quicStreamManagerAllocator("quicStreamManagerAllocator");
-ClassAllocator<QUICBidirectionalStream> 
quicBidiStreamAllocator("quicStreamAllocator");
 
 QUICStreamManager::QUICStreamManager(QUICConnectionInfoProvider *info, 
QUICRTTProvider *rtt_provider, QUICApplicationMap *app_map)
-  : _info(info), _rtt_provider(rtt_provider), _app_map(app_map)
+  : _stream_factory(rtt_provider, info), _info(info), _app_map(app_map)
 {
   if (this->_info->direction() == NET_VCONNECTION_OUT) {
     this->_next_stream_id_bidi = 
static_cast<uint32_t>(QUICStreamType::CLIENT_BIDI);
@@ -309,7 +308,6 @@ QUICStreamManager::_find_or_create_stream_vc(QUICStreamId 
stream_id)
         local_max_stream_data  = 
this->_local_tp->getAsUInt(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA_BIDI_LOCAL);
         remote_max_stream_data = 
this->_remote_tp->getAsUInt(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA_BIDI_REMOTE);
       }
-
       break;
     case QUICStreamType::SERVER_UNI:
       if (this->_remote_max_streams_uni == 0 || stream_id > 
this->_remote_max_streams_uni) {
@@ -318,15 +316,14 @@ QUICStreamManager::_find_or_create_stream_vc(QUICStreamId 
stream_id)
 
       local_max_stream_data  = 
this->_local_tp->getAsUInt(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA_UNI);
       remote_max_stream_data = 
this->_remote_tp->getAsUInt(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA_UNI);
-
+      break;
+    default:
+      ink_release_assert(false);
       break;
     }
 
-    // TODO Free the stream somewhere
-    stream = THREAD_ALLOC(quicBidiStreamAllocator, this_ethread());
-    new (stream)
-      QUICBidirectionalStream(this->_rtt_provider, this->_info, stream_id, 
local_max_stream_data, remote_max_stream_data);
-
+    stream = this->_stream_factory.create(stream_id, local_max_stream_data, 
remote_max_stream_data);
+    ink_assert(stream != nullptr);
     this->stream_list.push(stream);
   }
 
diff --git a/iocore/net/quic/QUICStreamManager.h 
b/iocore/net/quic/QUICStreamManager.h
index 26e4396..d618afb 100644
--- a/iocore/net/quic/QUICStreamManager.h
+++ b/iocore/net/quic/QUICStreamManager.h
@@ -25,19 +25,19 @@
 
 #include "QUICTypes.h"
 #include "QUICBidirectionalStream.h"
+#include "QUICUnidirectionalStream.h"
 #include "QUICApplicationMap.h"
 #include "QUICFrameHandler.h"
 #include "QUICFrame.h"
+#include "QUICStreamFactory.h"
 #include "QUICLossDetector.h"
 
-extern ClassAllocator<QUICBidirectionalStream> quicBidiStreamAllocator;
-
 class QUICTransportParameters;
 
 class QUICStreamManager : public QUICFrameHandler, public QUICFrameGenerator
 {
 public:
-  QUICStreamManager(){};
+  QUICStreamManager() : _stream_factory(nullptr, nullptr){};
   QUICStreamManager(QUICConnectionInfoProvider *info, QUICRTTProvider 
*rtt_provider, QUICApplicationMap *app_map);
 
   void init_flow_control_params(const std::shared_ptr<const 
QUICTransportParameters> &local_tp,
@@ -86,8 +86,9 @@ private:
     };
   }
 
+  QUICStreamFactory _stream_factory;
+
   QUICConnectionInfoProvider *_info                         = nullptr;
-  QUICRTTProvider *_rtt_provider                            = nullptr;
   QUICApplicationMap *_app_map                              = nullptr;
   std::shared_ptr<const QUICTransportParameters> _local_tp  = nullptr;
   std::shared_ptr<const QUICTransportParameters> _remote_tp = nullptr;
diff --git a/iocore/net/quic/QUICTypes.cc b/iocore/net/quic/QUICTypes.cc
index 85dedd6..28c363a 100644
--- a/iocore/net/quic/QUICTypes.cc
+++ b/iocore/net/quic/QUICTypes.cc
@@ -68,6 +68,28 @@ QUICTypeUtil::detect_stream_type(QUICStreamId id)
   return static_cast<QUICStreamType>(type);
 }
 
+QUICStreamDirection
+QUICTypeUtil::detect_stream_direction(QUICStreamId id, NetVConnectionContext_t 
context)
+{
+  switch (QUICTypeUtil::detect_stream_type(id)) {
+  case QUICStreamType::CLIENT_BIDI:
+  case QUICStreamType::SERVER_BIDI:
+    return QUICStreamDirection::BIDIRECTIONAL;
+  case QUICStreamType::CLIENT_UNI:
+    if (context == NET_VCONNECTION_OUT) {
+      return QUICStreamDirection::SEND;
+    }
+    return QUICStreamDirection::RECEIVE;
+  case QUICStreamType::SERVER_UNI:
+    if (context == NET_VCONNECTION_IN) {
+      return QUICStreamDirection::SEND;
+    }
+    return QUICStreamDirection::RECEIVE;
+  default:
+    return QUICStreamDirection::UNKNOWN;
+  }
+}
+
 QUICEncryptionLevel
 QUICTypeUtil::encryption_level(QUICPacketType type)
 {
diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h
index 3369854..76d0874 100644
--- a/iocore/net/quic/QUICTypes.h
+++ b/iocore/net/quic/QUICTypes.h
@@ -26,6 +26,10 @@
 #include <cstring>
 #include "tscore/ink_endian.h"
 #include "tscore/ink_hrtime.h"
+#include "tscore/Ptr.h"
+#include "I_EventSystem.h"
+
+#include "I_NetVConnection.h"
 
 #include <memory>
 #include <random>
@@ -431,6 +435,13 @@ enum class QUICStreamType : uint8_t {
   SERVER_UNI,
 };
 
+enum class QUICStreamDirection : uint8_t {
+  UNKNOWN = 0,
+  SEND,
+  RECEIVE,
+  BIDIRECTIONAL,
+};
+
 class QUICFiveTuple
 {
 public:
@@ -489,6 +500,7 @@ class QUICTypeUtil
 public:
   static bool is_supported_version(QUICVersion version);
   static QUICStreamType detect_stream_type(QUICStreamId id);
+  static QUICStreamDirection detect_stream_direction(QUICStreamId id, 
NetVConnectionContext_t context);
   static QUICEncryptionLevel encryption_level(QUICPacketType type);
   static QUICPacketType packet_type(QUICEncryptionLevel level);
   static QUICKeyPhase key_phase(QUICPacketType type);
diff --git a/iocore/net/quic/QUICUnidirectionalStream.h 
b/iocore/net/quic/QUICUnidirectionalStream.h
index 6c324a7..0c71627 100644
--- a/iocore/net/quic/QUICUnidirectionalStream.h
+++ b/iocore/net/quic/QUICUnidirectionalStream.h
@@ -30,6 +30,9 @@ class QUICSendStream : public QUICStreamVConnection
 public:
   QUICSendStream(QUICConnectionInfoProvider *cinfo, QUICStreamId sid, uint64_t 
send_max_stream_data);
   QUICSendStream() : _remote_flow_controller(0, 0), _state(nullptr, nullptr) {}
+
+  ~QUICSendStream() {}
+
   int state_stream_open(int event, void *data);
   int state_stream_closed(int event, void *data);
 
@@ -77,6 +80,8 @@ public:
                     uint64_t recv_max_stream_data);
   QUICReceiveStream() : _local_flow_controller(nullptr, 0, 0), _state(nullptr, 
nullptr) {}
 
+  ~QUICReceiveStream() {}
+
   int state_stream_open(int event, void *data);
   int state_stream_closed(int event, void *data);
 

Reply via email to