This is an automated email from the ASF dual-hosted git repository. maskit 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 5575369 Delegate creating QUIC application to SessionAccept 5575369 is described below commit 5575369ad6f09f3b3f24a4b9c422f77d37341302 Author: Masakazu Kitajo <mas...@apache.org> AuthorDate: Tue Sep 26 11:53:42 2017 +0900 Delegate creating QUIC application to SessionAccept --- iocore/net/Makefile.am | 2 + iocore/net/P_QUICNetVConnection.h | 2 +- iocore/net/P_QUICNextProtocolAccept.h | 61 ++++++++++++++++++++ iocore/net/P_QUICPacketHandler.h | 1 + iocore/net/QUICNetVConnection.cc | 41 ++++---------- iocore/net/QUICNextProtocolAccept.cc | 103 ++++++++++++++++++++++++++++++++++ iocore/net/QUICPacketHandler.cc | 1 + iocore/net/quic/Makefile.am | 4 +- iocore/net/quic/Mock.h | 95 ++++++++++++++++--------------- iocore/net/quic/QUICConnection.h | 3 + iocore/net/quic/QUICSimpleApp.cc | 6 +- iocore/net/quic/QUICSimpleApp.h | 2 +- iocore/net/quic/QUICStreamManager.cc | 6 ++ iocore/net/quic/QUICStreamManager.h | 2 + proxy/hq/HQClientSession.cc | 3 +- proxy/hq/HQSessionAccept.cc | 9 +-- proxy/hq/Makefile.am | 3 +- proxy/http/HttpProxyServerMain.cc | 10 +++- 18 files changed, 262 insertions(+), 92 deletions(-) diff --git a/iocore/net/Makefile.am b/iocore/net/Makefile.am index 10ce90d..faad241 100644 --- a/iocore/net/Makefile.am +++ b/iocore/net/Makefile.am @@ -107,6 +107,7 @@ libinknet_a_SOURCES = \ P_SSLNetProcessor.h \ P_SSLNetVConnection.h \ P_SSLNextProtocolAccept.h \ + P_QUICNextProtocolAccept.h \ P_SSLNextProtocolSet.h \ P_SSLUtils.h \ P_SSLClientUtils.h \ @@ -132,6 +133,7 @@ libinknet_a_SOURCES = \ SSLNetProcessor.cc \ SSLNetVConnection.cc \ SSLNextProtocolAccept.cc \ + QUICNextProtocolAccept.cc \ SSLNextProtocolSet.cc \ SSLUtils.cc \ SSLClientUtils.cc \ diff --git a/iocore/net/P_QUICNetVConnection.h b/iocore/net/P_QUICNetVConnection.h index ae11bf2..6ce3194 100644 --- a/iocore/net/P_QUICNetVConnection.h +++ b/iocore/net/P_QUICNetVConnection.h @@ -173,6 +173,7 @@ public: uint32_t maximum_quic_packet_size() override; uint32_t minimum_quic_packet_size() override; uint32_t maximum_stream_frame_data_size() override; + QUICStreamManager *stream_manager() override; uint32_t pmtu() override; NetVConnectionContext_t direction() override; SSLNextProtocolSet *next_protocol_set() override; @@ -244,7 +245,6 @@ private: Ptr<ProxyMutex> _packet_transmitter_mutex; Ptr<ProxyMutex> _frame_transmitter_mutex; - QUICApplication *_create_application(); void _init_flow_control_params(const std::shared_ptr<const QUICTransportParameters> &local_tp, const std::shared_ptr<const QUICTransportParameters> &remote_tp); diff --git a/iocore/net/P_QUICNextProtocolAccept.h b/iocore/net/P_QUICNextProtocolAccept.h new file mode 100644 index 0000000..5b03652 --- /dev/null +++ b/iocore/net/P_QUICNextProtocolAccept.h @@ -0,0 +1,61 @@ +/** @file + + QUICNextProtocolAccept + + @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 "P_QUICNetVConnection.h" +#include "P_SSLNextProtocolSet.h" +#include "I_IOBuffer.h" + +class QUICNextProtocolAccept : public SessionAccept +{ +public: + QUICNextProtocolAccept(); + ~QUICNextProtocolAccept(); + + bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *); + + // Register handler as an endpoint for the specified protocol. Neither + // handler nor protocol are copied, so the caller must guarantee their + // lifetime is at least as long as that of the acceptor. + bool registerEndpoint(const char *protocol, Continuation *handler); + + // Unregister the handler. Returns false if this protocol is not registered + // or if it is not registered for the specified handler. + bool unregisterEndpoint(const char *protocol, Continuation *handler); + + SLINK(QUICNextProtocolAccept, link); + SSLNextProtocolSet *getProtoSet(); + SSLNextProtocolSet *cloneProtoSet(); + + // noncopyable + QUICNextProtocolAccept(const QUICNextProtocolAccept &) = delete; // disabled + QUICNextProtocolAccept &operator=(const QUICNextProtocolAccept &) = delete; // disabled + +private: + int mainEvent(int event, void *netvc); + + SSLNextProtocolSet protoset; + + friend struct QUICNextProtocolTrampoline; +}; diff --git a/iocore/net/P_QUICPacketHandler.h b/iocore/net/P_QUICPacketHandler.h index 6b29b6a..e1ea3fb 100644 --- a/iocore/net/P_QUICPacketHandler.h +++ b/iocore/net/P_QUICPacketHandler.h @@ -26,6 +26,7 @@ #include "ts/ink_platform.h" #include "P_Connection.h" #include "P_NetAccept.h" +#include "quic/QUICTypes.h" class QUICNetVConnection; class QUICPacket; diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc index 978ea10..87e749a 100644 --- a/iocore/net/QUICNetVConnection.cc +++ b/iocore/net/QUICNetVConnection.cc @@ -35,8 +35,6 @@ #include "P_SSLNextProtocolSet.h" -#include "QUICEchoApp.h" -#include "QUICSimpleApp.h" #include "QUICDebugNames.h" #include "QUICEvents.h" #include "QUICConfig.h" @@ -67,11 +65,6 @@ QUICNetVConnection::init(UDPConnection *udp_con, QUICPacketHandler *packet_handl this->_udp_con = udp_con; this->_packet_handler = packet_handler; this->_quic_connection_id.randomize(); - - // FIXME These should be done by HttpProxyServerMain - SSLNextProtocolSet *next_protocol_set = new SSLNextProtocolSet(); - next_protocol_set->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_QUIC, nullptr); - this->registerNextProtocolSet(next_protocol_set); } VIO * @@ -199,6 +192,12 @@ QUICNetVConnection::maximum_stream_frame_data_size() return this->maximum_quic_packet_size() - MAX_STREAM_FRAME_OVERHEAD - MAX_PACKET_OVERHEAD; } +QUICStreamManager * +QUICNetVConnection::stream_manager() +{ + return this->_stream_manager; +} + void QUICNetVConnection::_transmit_packet(QUICPacketPtr packet) { @@ -407,12 +406,17 @@ QUICNetVConnection::state_handshake(int event, Event *data) } if (this->_handshake_handler && this->_handshake_handler->is_completed()) { - this->_application_map->set_default(this->_create_application()); this->_init_flow_control_params(this->_handshake_handler->local_transport_parameters(), this->_handshake_handler->remote_transport_parameters()); DebugQUICCon("Enter state_connection_established"); SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_established); + + const uint8_t *app_name; + unsigned int app_name_len = 0; + this->_handshake_handler->negotiated_application_name(&app_name, &app_name_len); + Continuation *endpoint = this->_next_protocol_set->findEndpoint(app_name, app_name_len); + endpoint->handleEvent(NET_EVENT_ACCEPT, this); } return EVENT_CONT; @@ -790,27 +794,6 @@ QUICNetVConnection::_build_packet(ats_unique_buf buf, size_t len, bool retransmi return packet; } -QUICApplication * -QUICNetVConnection::_create_application() -{ - const uint8_t *app_name; - unsigned int app_name_len = 0; - this->_handshake_handler->negotiated_application_name(&app_name, &app_name_len); - if (app_name) { - DebugQUICCon("ALPN: %.*s", app_name_len, app_name); - if (memcmp(TS_ALPN_PROTOCOL_HTTP_QUIC, app_name, app_name_len) == 0) { - return new QUICSimpleApp(this, this); - } else { - DebugQUICCon("Negotiated application is not available"); - ink_assert(false); - return nullptr; - } - } else { - DebugQUICCon("Failed to negotiate application"); - return nullptr; - } -} - void QUICNetVConnection::_init_flow_control_params(const std::shared_ptr<const QUICTransportParameters> &local_tp, const std::shared_ptr<const QUICTransportParameters> &remote_tp) diff --git a/iocore/net/QUICNextProtocolAccept.cc b/iocore/net/QUICNextProtocolAccept.cc new file mode 100644 index 0000000..bdd89ed --- /dev/null +++ b/iocore/net/QUICNextProtocolAccept.cc @@ -0,0 +1,103 @@ +/** @file + + QUICNextProtocolAccept + + @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 "P_QUICNextProtocolAccept.h" + +static QUICNetVConnection * +quic_netvc_cast(int event, void *edata) +{ + union { + VIO *vio; + NetVConnection *vc; + } ptr; + + switch (event) { + case NET_EVENT_ACCEPT: + ptr.vc = static_cast<NetVConnection *>(edata); + return dynamic_cast<QUICNetVConnection *>(ptr.vc); + case VC_EVENT_INACTIVITY_TIMEOUT: + case VC_EVENT_READ_COMPLETE: + case VC_EVENT_ERROR: + ptr.vio = static_cast<VIO *>(edata); + return dynamic_cast<QUICNetVConnection *>(ptr.vio->vc_server); + default: + return nullptr; + } +} + +int +QUICNextProtocolAccept::mainEvent(int event, void *edata) +{ + QUICNetVConnection *netvc = quic_netvc_cast(event, edata); + + Debug("quic", "[QUICNextProtocolAccept:mainEvent] event %d netvc %p", event, netvc); + switch (event) { + case NET_EVENT_ACCEPT: + ink_release_assert(netvc != nullptr); + netvc->registerNextProtocolSet(&this->protoset); + return EVENT_CONT; + default: + netvc->do_io_close(); + return EVENT_DONE; + } +} + +bool +QUICNextProtocolAccept::accept(NetVConnection *, MIOBuffer *, IOBufferReader *) +{ + ink_release_assert(0); + return false; +} + +bool +QUICNextProtocolAccept::registerEndpoint(const char *protocol, Continuation *handler) +{ + return this->protoset.registerEndpoint(protocol, handler); +} + +bool +QUICNextProtocolAccept::unregisterEndpoint(const char *protocol, Continuation *handler) +{ + return this->protoset.unregisterEndpoint(protocol, handler); +} + +QUICNextProtocolAccept::QUICNextProtocolAccept() : SessionAccept(nullptr) +{ + SET_HANDLER(&QUICNextProtocolAccept::mainEvent); +} + +SSLNextProtocolSet * +QUICNextProtocolAccept::getProtoSet() +{ + return &this->protoset; +} + +SSLNextProtocolSet * +QUICNextProtocolAccept::cloneProtoSet() +{ + return this->protoset.clone(); +} + +QUICNextProtocolAccept::~QUICNextProtocolAccept() +{ +} diff --git a/iocore/net/QUICPacketHandler.cc b/iocore/net/QUICPacketHandler.cc index 39df7ce..3558221 100644 --- a/iocore/net/QUICPacketHandler.cc +++ b/iocore/net/QUICPacketHandler.cc @@ -158,6 +158,7 @@ QUICPacketHandler::_recv_packet(int event, UDPPacket *udpPacket) vc->options.ip_family = udpPacket->from.sa.sa_family; this->_connections.put(cid, vc); + this->action_->continuation->handleEvent(NET_EVENT_ACCEPT, vc); } std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> qPkt = QUICPacketFactory::create(block, vc->largest_received_packet_number()); diff --git a/iocore/net/quic/Makefile.am b/iocore/net/quic/Makefile.am index 34463d7..90ba2fe 100644 --- a/iocore/net/quic/Makefile.am +++ b/iocore/net/quic/Makefile.am @@ -61,9 +61,7 @@ libquic_a_SOURCES = \ QUICConfig.cc \ QUICDebugNames.cc \ QUICApplication.cc \ - QUICApplicationMap.cc \ - QUICEchoApp.cc \ - QUICSimpleApp.cc + QUICApplicationMap.cc include $(top_srcdir)/build/tidy.mk diff --git a/iocore/net/quic/Mock.h b/iocore/net/quic/Mock.h index 66f8f56..af097ce 100644 --- a/iocore/net/quic/Mock.h +++ b/iocore/net/quic/Mock.h @@ -28,6 +28,50 @@ #include "QUICEvents.h" #include "QUICPacketTransmitter.h" +class MockQUICStreamManager : public QUICStreamManager +{ +public: + MockQUICStreamManager() : QUICStreamManager() {} + // Override + virtual QUICError + handle_frame(std::shared_ptr<const QUICFrame> f) override + { + ++_frameCount[static_cast<int>(f->type())]; + ++_totalFrameCount; + + return QUICError(QUICErrorClass::NONE); + } + + // for Test + int + getStreamFrameCount() + { + return _frameCount[static_cast<int>(QUICFrameType::STREAM)]; + } + + int + getAckFrameCount() + { + return _frameCount[static_cast<int>(QUICFrameType::ACK)]; + } + + int + getPingFrameCount() + { + return _frameCount[static_cast<int>(QUICFrameType::PING)]; + } + + int + getTotalFrameCount() + { + return _totalFrameCount; + } + +private: + int _totalFrameCount = 0; + int _frameCount[256] = {0}; +}; + class MockNetVConnection : public NetVConnection { public: @@ -197,11 +241,18 @@ public: return _totalFrameCount; } + QUICStreamManager * + stream_manager() override + { + return &_stream_manager; + } + int _transmit_count = 0; int _retransmit_count = 0; Ptr<ProxyMutex> _mutex; int _totalFrameCount = 0; int _frameCount[256] = {0}; + MockQUICStreamManager _stream_manager; QUICTransportParametersInEncryptedExtensions dummy_transport_parameters; NetVConnectionContext_t _direction; @@ -267,50 +318,6 @@ public: } }; -class MockQUICStreamManager : public QUICStreamManager -{ -public: - MockQUICStreamManager() : QUICStreamManager() {} - // Override - virtual QUICError - handle_frame(std::shared_ptr<const QUICFrame> f) override - { - ++_frameCount[static_cast<int>(f->type())]; - ++_totalFrameCount; - - return QUICError(QUICErrorClass::NONE); - } - - // for Test - int - getStreamFrameCount() - { - return _frameCount[static_cast<int>(QUICFrameType::STREAM)]; - } - - int - getAckFrameCount() - { - return _frameCount[static_cast<int>(QUICFrameType::ACK)]; - } - - int - getPingFrameCount() - { - return _frameCount[static_cast<int>(QUICFrameType::PING)]; - } - - int - getTotalFrameCount() - { - return _totalFrameCount; - } - -private: - int _totalFrameCount = 0; - int _frameCount[256] = {0}; -}; - class MockQUICCongestionController : public QUICCongestionController { public: diff --git a/iocore/net/quic/QUICConnection.h b/iocore/net/quic/QUICConnection.h index 69dfea6..6901819 100644 --- a/iocore/net/quic/QUICConnection.h +++ b/iocore/net/quic/QUICConnection.h @@ -29,6 +29,7 @@ #include "QUICTransportParameters.h" class QUICApplication; +class QUICStreamManager; class SSLNextProtocolSet; class QUICConnection : public QUICPacketTransmitter, public QUICFrameTransmitter, public QUICFrameHandler @@ -49,6 +50,8 @@ public: */ virtual uint32_t minimum_quic_packet_size() = 0; + virtual QUICStreamManager *stream_manager() = 0; + virtual uint32_t pmtu() = 0; virtual NetVConnectionContext_t direction() = 0; virtual SSLNextProtocolSet *next_protocol_set() = 0; diff --git a/iocore/net/quic/QUICSimpleApp.cc b/iocore/net/quic/QUICSimpleApp.cc index 82dc21d..f7424d1 100644 --- a/iocore/net/quic/QUICSimpleApp.cc +++ b/iocore/net/quic/QUICSimpleApp.cc @@ -32,14 +32,16 @@ static constexpr char tag[] = "quic_simple_app"; -QUICSimpleApp::QUICSimpleApp(QUICNetVConnection *client_vc, QUICConnection *qc) : QUICApplication(qc) +QUICSimpleApp::QUICSimpleApp(QUICNetVConnection *client_vc) : QUICApplication(client_vc) { - // FIXME: initialize on HQSessionAccept sockaddr const *client_ip = client_vc->get_remote_addr(); const AclRecord *session_acl_record = SessionAccept::testIpAllowPolicy(client_ip); this->_client_session = new HQClientSession(client_vc); this->_client_session->acl_record = session_acl_record; + this->_client_session->new_connection(client_vc, nullptr, nullptr, false); + + this->_client_qc->stream_manager()->set_default_application(this); SET_HANDLER(&QUICSimpleApp::main_event_handler); } diff --git a/iocore/net/quic/QUICSimpleApp.h b/iocore/net/quic/QUICSimpleApp.h index c658133..12804eb 100644 --- a/iocore/net/quic/QUICSimpleApp.h +++ b/iocore/net/quic/QUICSimpleApp.h @@ -36,7 +36,7 @@ class HQClientSession; class QUICSimpleApp : public QUICApplication { public: - QUICSimpleApp(QUICNetVConnection *client_vc, QUICConnection *qc); + QUICSimpleApp(QUICNetVConnection *client_vc); ~QUICSimpleApp(); int main_event_handler(int event, Event *data); diff --git a/iocore/net/quic/QUICStreamManager.cc b/iocore/net/quic/QUICStreamManager.cc index 24f8fb8..d79245c 100644 --- a/iocore/net/quic/QUICStreamManager.cc +++ b/iocore/net/quic/QUICStreamManager.cc @@ -258,3 +258,9 @@ QUICStreamManager::stream_count() const } return count; } + +void +QUICStreamManager::set_default_application(QUICApplication *app) +{ + this->_app_map->set_default(app); +} diff --git a/iocore/net/quic/QUICStreamManager.h b/iocore/net/quic/QUICStreamManager.h index 3fa81ef..284a93d 100644 --- a/iocore/net/quic/QUICStreamManager.h +++ b/iocore/net/quic/QUICStreamManager.h @@ -45,6 +45,8 @@ public: uint64_t total_offset_sent() const; uint32_t stream_count() const; + void set_default_application(QUICApplication *app); + DLL<QUICStream> stream_list; // QUICFrameHandler diff --git a/proxy/hq/HQClientSession.cc b/proxy/hq/HQClientSession.cc index e38d086..27d1961 100644 --- a/proxy/hq/HQClientSession.cc +++ b/proxy/hq/HQClientSession.cc @@ -87,7 +87,8 @@ HQClientSession::start() void HQClientSession::new_connection(NetVConnection *new_vc, MIOBuffer *iobuf, IOBufferReader *reader, bool backdoor) { - ink_assert(false); + this->con_id = ProxyClientSession::next_connection_id(); + return; } diff --git a/proxy/hq/HQSessionAccept.cc b/proxy/hq/HQSessionAccept.cc index a98e44e..a053398 100644 --- a/proxy/hq/HQSessionAccept.cc +++ b/proxy/hq/HQSessionAccept.cc @@ -26,6 +26,7 @@ #include "P_Net.h" #include "I_Machine.h" #include "../IPAllow.h" +#include "QUICSimpleApp.h" HQSessionAccept::HQSessionAccept(const HttpSessionAccept::Options &_o) : SessionAccept(nullptr), options(_o) { @@ -55,13 +56,7 @@ HQSessionAccept::accept(NetVConnection *netvc, MIOBuffer *iobuf, IOBufferReader ats_ip_nptop(client_ip, ipb, sizeof(ipb)), netvc->attributes); } - ink_assert(false); - // Not implemented yet - - // HQClientSession *new_session = THREAD_ALLOC_INIT(quicClientSessionAllocator, this_ethread()); - // new_session->acl_record = session_acl_record; - // new_session->new_connection(netvc, iobuf, reader, false /* backdoor */); - // static_cast<QUICNetVConnection *>(netvc)->set_application(new_session); + new QUICSimpleApp(static_cast<QUICNetVConnection *>(netvc)); return true; } diff --git a/proxy/hq/Makefile.am b/proxy/hq/Makefile.am index da9e2ff..955b092 100644 --- a/proxy/hq/Makefile.am +++ b/proxy/hq/Makefile.am @@ -38,7 +38,8 @@ libhq_a_SOURCES = \ HQ.cc \ HQSessionAccept.cc \ HQClientSession.cc \ - HQClientTransaction.cc + HQClientTransaction.cc \ + $(abs_top_srcdir)/iocore/net/quic/QUICSimpleApp.cc tidy-local: $(libhq_a_SOURCES) \ $(CXX_Clang_Tidy) diff --git a/proxy/http/HttpProxyServerMain.cc b/proxy/http/HttpProxyServerMain.cc index acde339..36d8fe7 100644 --- a/proxy/http/HttpProxyServerMain.cc +++ b/proxy/http/HttpProxyServerMain.cc @@ -40,6 +40,7 @@ #include "http2/Http2SessionAccept.h" #include "HttpConnectionCount.h" #if TS_USE_QUIC == 1 +#include "P_QUICNextProtocolAccept.h" #include "hq/HQSessionAccept.h" #endif @@ -223,12 +224,15 @@ MakeHttpProxyAcceptor(HttpProxyAcceptor &acceptor, HttpProxyPort &port, unsigned acceptor._accept = ssl; #if TS_USE_QUIC == 1 } else if (port.isQUIC()) { + QUICNextProtocolAccept *quic = new QUICNextProtocolAccept(); + // HTTP/QUIC if (port.m_session_protocol_preference.contains(TS_ALPN_PROTOCOL_INDEX_HTTP_QUIC)) { - HQSessionAccept *hq = new HQSessionAccept(accept_opt); - // FIXME hq should be registered to QUICNextProtocolAccept like SSL - acceptor._accept = hq; + quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_QUIC, new HQSessionAccept(accept_opt)); } + + quic->proxyPort = &port; + acceptor._accept = quic; #endif } else { acceptor._accept = probe; -- To stop receiving notification emails like this one, please contact ['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].