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
commit 7cb18b38d88fd6af13eed65867701117cbc890ae Author: Masakazu Kitajo <mas...@apache.org> AuthorDate: Tue May 15 16:40:57 2018 +0900 Capsulate how to read QUIC packets from UDP packets To prepare for coalescing packets --- iocore/net/P_QUICNetVConnection.h | 6 +-- iocore/net/QUICNetVConnection.cc | 64 ++++++++----------------------- iocore/net/quic/Makefile.am | 1 + iocore/net/quic/Mock.h | 6 --- iocore/net/quic/QUICConnection.h | 1 - iocore/net/quic/QUICPacketReceiveQueue.cc | 61 +++++++++++++++++++++++++++++ iocore/net/quic/QUICPacketReceiveQueue.h | 46 ++++++++++++++++++++++ 7 files changed, 126 insertions(+), 59 deletions(-) diff --git a/iocore/net/P_QUICNetVConnection.h b/iocore/net/P_QUICNetVConnection.h index 745d7c5..a327772 100644 --- a/iocore/net/P_QUICNetVConnection.h +++ b/iocore/net/P_QUICNetVConnection.h @@ -59,6 +59,7 @@ #include "quic/QUICAltConnectionManager.h" #include "quic/QUICPathValidator.h" #include "quic/QUICApplicationMap.h" +#include "quic/QUICPacketReceiveQueue.h" // These are included here because older OpenQUIC libraries don't have them. // Don't copy these defines, or use their values directly, they are merely @@ -197,7 +198,6 @@ public: NetVConnectionContext_t direction() override; SSLNextProtocolSet *next_protocol_set() override; void close(QUICConnectionErrorUPtr error) override; - QUICPacketNumber largest_received_packet_number() override; QUICPacketNumber largest_acked_packet_number() override; void handle_received_packet(UDPPacket *packet) override; bool is_closed() override; @@ -231,7 +231,6 @@ private: QUICConnectionId _quic_connection_id; QUICFiveTuple _five_tuple; - QUICPacketNumber _largest_received_packet_number = 0; UDPConnection *_udp_con = nullptr; QUICPacketHandler *_packet_handler = nullptr; QUICPacketFactory _packet_factory; @@ -258,9 +257,8 @@ private: QUICAltConnectionManager *_alt_con_manager = nullptr; QUICPathValidator *_path_validator = nullptr; - CountQueue<UDPPacket> _packet_recv_queue; + QUICPacketReceiveQueue _packet_recv_queue = {this->_packet_factory}; CountQueue<QUICPacket> _packet_send_queue; - std::queue<QUICPacketUPtr> _quic_packet_recv_queue; QUICConnectionErrorUPtr _connection_error = nullptr; uint32_t _state_closing_recv_packet_count = 0; diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc index 2557e25..a924e74 100644 --- a/iocore/net/QUICNetVConnection.cc +++ b/iocore/net/QUICNetVConnection.cc @@ -789,12 +789,6 @@ QUICNetVConnection::next_protocol_set() } QUICPacketNumber -QUICNetVConnection::largest_received_packet_number() -{ - return this->_largest_received_packet_number; -} - -QUICPacketNumber QUICNetVConnection::largest_acked_packet_number() { return this->_loss_detector->largest_acked_packet_number(); @@ -885,7 +879,7 @@ QUICNetVConnection::_state_handshake_process_retry_packet(QUICPacketUPtr packet) QUICErrorUPtr error = this->_recv_and_ack(std::move(packet)); // Packet number of RETRY packet is echo of INITIAL packet - this->_largest_received_packet_number = 0; + this->_packet_recv_queue.reset(); this->_stream_manager->reset_recv_offset(); // Generate new Connection ID @@ -982,7 +976,7 @@ QUICNetVConnection::_state_common_receive_packet() QUICErrorUPtr QUICNetVConnection::_state_closing_receive_packet() { - while (this->_packet_recv_queue.size > 0) { + while (this->_packet_recv_queue.size() > 0) { QUICPacketCreationResult result; QUICPacketUPtr packet = this->_dequeue_recv_packet(result); if (result == QUICPacketCreationResult::SUCCESS) { @@ -1006,7 +1000,7 @@ QUICNetVConnection::_state_closing_receive_packet() QUICErrorUPtr QUICNetVConnection::_state_draining_receive_packet() { - while (this->_packet_recv_queue.size > 0) { + while (this->_packet_recv_queue.size() > 0) { QUICPacketCreationResult result; QUICPacketUPtr packet = this->_dequeue_recv_packet(result); if (result == QUICPacketCreationResult::SUCCESS) { @@ -1277,10 +1271,6 @@ QUICNetVConnection::_recv_and_ack(QUICPacketUPtr packet) uint16_t size = packet->payload_length(); QUICPacketNumber packet_num = packet->packet_number(); - if (packet_num > this->_largest_received_packet_number) { - this->_largest_received_packet_number = packet_num; - } - bool should_send_ack; QUICErrorUPtr error = QUICErrorUPtr(new QUICNoError()); @@ -1338,7 +1328,7 @@ QUICNetVConnection::_build_packet(ats_unique_buf buf, size_t len, bool retransmi case QUICPacketType::RETRY: // Echo "_largest_received_packet_number" as packet number. Probably this is the packet number from triggering client packet. packet = this->_packet_factory.create_retry_packet(this->_peer_quic_connection_id, this->_quic_connection_id, - this->_largest_received_packet_number, std::move(buf), len, retransmittable); + this->_packet_recv_queue.largest_received_packet_number(), std::move(buf), len, retransmittable); break; case QUICPacketType::HANDSHAKE: packet = @@ -1417,46 +1407,28 @@ QUICNetVConnection::_handle_error(QUICErrorUPtr error) QUICPacketUPtr QUICNetVConnection::_dequeue_recv_packet(QUICPacketCreationResult &result) { - QUICPacketUPtr quic_packet = QUICPacketFactory::create_null_packet(); - UDPPacket *udp_packet = this->_packet_recv_queue.dequeue(); - if (!udp_packet) { - result = QUICPacketCreationResult::NOT_READY; - return quic_packet; - } + QUICPacketUPtr packet = this->_packet_recv_queue.dequeue(result); if (this->direction() == NET_VCONNECTION_OUT) { // Reset CID if a server sent back a new CID // FIXME This should happen only once - IOBufferBlock *block = udp_packet->getIOBlockChain(); - if (QUICTypeUtil::has_connection_id(reinterpret_cast<const uint8_t *>(block->buf()))) { - QUICConnectionId cid = QUICPacket::destination_connection_id(reinterpret_cast<const uint8_t *>(block->buf())); + QUICConnectionId cid = packet->destination_cid(); + if (cid.length()) { if (this->_quic_connection_id != cid) { this->_quic_connection_id = cid; } } } - // Create a QUIC packet - ats_unique_buf pkt = ats_unique_malloc(udp_packet->getPktLength()); - IOBufferBlock *b = udp_packet->getIOBlockChain(); - size_t written = 0; - while (b) { - memcpy(pkt.get() + written, b->buf(), b->read_avail()); - written += b->read_avail(); - b = b->next.get(); + if (result == QUICPacketCreationResult::SUCCESS) { + this->_last_received_packet_type = packet->type(); + this->_packet_factory.set_dcil(packet->destination_cid().length()); } - quic_packet = - this->_packet_factory.create(udp_packet->from, std::move(pkt), written, this->largest_received_packet_number(), result); - udp_packet->free(); - + // Debug prints switch (result) { case QUICPacketCreationResult::NOT_READY: QUICConDebug("Not ready to decrypt the packet"); - // FIXME: unordered packet should be buffered and retried - if (this->_packet_recv_queue.size > 0) { - result = QUICPacketCreationResult::IGNORED; - } break; case QUICPacketCreationResult::IGNORED: QUICConDebug("Ignored"); @@ -1465,23 +1437,19 @@ QUICNetVConnection::_dequeue_recv_packet(QUICPacketCreationResult &result) QUICConDebug("Unsupported version"); break; case QUICPacketCreationResult::SUCCESS: - this->_last_received_packet_type = quic_packet->type(); - this->_packet_factory.set_dcil(quic_packet->destination_cid().length()); - - if (quic_packet->type() == QUICPacketType::VERSION_NEGOTIATION) { - QUICConDebug("Dequeue %s size=%u", QUICDebugNames::packet_type(quic_packet->type()), quic_packet->size()); + if (packet->type() == QUICPacketType::VERSION_NEGOTIATION) { + QUICConDebug("Dequeue %s size=%u", QUICDebugNames::packet_type(packet->type()), packet->size()); } else { - QUICConDebug("Dequeue %s pkt_num=%" PRIu64 " size=%u", QUICDebugNames::packet_type(quic_packet->type()), - quic_packet->packet_number(), quic_packet->size()); + QUICConDebug("Dequeue %s pkt_num=%" PRIu64 " size=%u", QUICDebugNames::packet_type(packet->type()), + packet->packet_number(), packet->size()); } - break; default: QUICConDebug("Failed to decrypt the packet"); break; } - return quic_packet; + return packet; } void diff --git a/iocore/net/quic/Makefile.am b/iocore/net/quic/Makefile.am index 6b8da87..d9787f5 100644 --- a/iocore/net/quic/Makefile.am +++ b/iocore/net/quic/Makefile.am @@ -74,6 +74,7 @@ libquic_a_SOURCES = \ QUICApplication.cc \ QUICApplicationMap.cc \ QUICIncomingFrameBuffer.cc \ + QUICPacketReceiveQueue.cc \ QUICPacketRetransmitter.cc \ QUICPathValidator.cc \ QUICStatelessRetry.cc diff --git a/iocore/net/quic/Mock.h b/iocore/net/quic/Mock.h index d1c6f8a..839bcfe 100644 --- a/iocore/net/quic/Mock.h +++ b/iocore/net/quic/Mock.h @@ -222,12 +222,6 @@ public: } QUICPacketNumber - largest_received_packet_number() override - { - return 0; - } - - QUICPacketNumber largest_acked_packet_number() override { return 0; diff --git a/iocore/net/quic/QUICConnection.h b/iocore/net/quic/QUICConnection.h index 747fc2d..83c83a8 100644 --- a/iocore/net/quic/QUICConnection.h +++ b/iocore/net/quic/QUICConnection.h @@ -62,7 +62,6 @@ public: virtual NetVConnectionContext_t direction() = 0; virtual SSLNextProtocolSet *next_protocol_set() = 0; virtual void close(QUICConnectionErrorUPtr error) = 0; - virtual QUICPacketNumber largest_received_packet_number() = 0; virtual QUICPacketNumber largest_acked_packet_number() = 0; virtual void handle_received_packet(UDPPacket *packeet) = 0; virtual bool is_closed() = 0; diff --git a/iocore/net/quic/QUICPacketReceiveQueue.cc b/iocore/net/quic/QUICPacketReceiveQueue.cc new file mode 100644 index 0000000..640dcaa --- /dev/null +++ b/iocore/net/quic/QUICPacketReceiveQueue.cc @@ -0,0 +1,61 @@ +#include "QUICPacketReceiveQueue.h" + +QUICPacketReceiveQueue::QUICPacketReceiveQueue(QUICPacketFactory &packet_factory) : _packet_factory(packet_factory) {} + +void +QUICPacketReceiveQueue::enqueue(UDPPacket *packet) +{ + this->_queue.enqueue(packet); +} + +QUICPacketUPtr +QUICPacketReceiveQueue::dequeue(QUICPacketCreationResult &result) +{ + QUICPacketUPtr quic_packet = QUICPacketFactory::create_null_packet(); + UDPPacket *udp_packet = this->_queue.dequeue(); + if (!udp_packet) { + result = QUICPacketCreationResult::NOT_READY; + return quic_packet; + } + + // Create a QUIC packet + ats_unique_buf pkt = ats_unique_malloc(udp_packet->getPktLength()); + IOBufferBlock *b = udp_packet->getIOBlockChain(); + size_t written = 0; + while (b) { + memcpy(pkt.get() + written, b->buf(), b->read_avail()); + written += b->read_avail(); + b = b->next.get(); + } + + quic_packet = + this->_packet_factory.create(udp_packet->from, std::move(pkt), written, this->largest_received_packet_number(), result); + udp_packet->free(); + + if (result == QUICPacketCreationResult::NOT_READY) { + // FIXME: unordered packet should be buffered and retried + if (this->_queue.size > 0) { + result = QUICPacketCreationResult::IGNORED; + } + } + + return quic_packet; +} + +uint32_t +QUICPacketReceiveQueue::size() +{ + return this->_queue.size; +} + +QUICPacketNumber +QUICPacketReceiveQueue::largest_received_packet_number() +{ + return this->_largest_received_packet_number; +} + +void +QUICPacketReceiveQueue::reset() +{ + this->_largest_received_packet_number = 0; +} diff --git a/iocore/net/quic/QUICPacketReceiveQueue.h b/iocore/net/quic/QUICPacketReceiveQueue.h new file mode 100644 index 0000000..a711bbd --- /dev/null +++ b/iocore/net/quic/QUICPacketReceiveQueue.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 "I_UDPPacket.h" +#include "ts/List.h" + +#include "QUICPacket.h" + +class QUICPacketReceiveQueue +{ +public: + QUICPacketReceiveQueue(QUICPacketFactory &packet_factory); + + void enqueue(UDPPacket *packet); + QUICPacketUPtr dequeue(QUICPacketCreationResult &result); + uint32_t size(); + QUICPacketNumber largest_received_packet_number(); + void reset(); + +private: + CountQueue<UDPPacket> _queue; + QUICPacketFactory &_packet_factory; + QUICPacketNumber _largest_received_packet_number = 0; +}; -- To stop receiving notification emails like this one, please contact mas...@apache.org.