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 <[email protected]>
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);