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);