This is an automated email from the ASF dual-hosted git repository. masaori 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 4e47161 Encode/Decode packet number 4e47161 is described below commit 4e471619c2b0d8a505beb1d7aaac148bc90da87d Author: Masaori Koshiba <masa...@apache.org> AuthorDate: Tue Sep 5 15:52:46 2017 +0900 Encode/Decode packet number --- iocore/net/P_QUICNetVConnection.h | 7 +- iocore/net/P_QUICPacketHandler.h | 1 + iocore/net/QUICNetVConnection.cc | 30 ++- iocore/net/QUICPacketHandler.cc | 36 +++- iocore/net/quic/Mock.h | 12 ++ iocore/net/quic/QUICConnection.h | 14 +- iocore/net/quic/QUICHandshake.cc | 3 +- iocore/net/quic/QUICLossDetector.cc | 6 + iocore/net/quic/QUICLossDetector.h | 1 + iocore/net/quic/QUICPacket.cc | 220 +++++++++++---------- iocore/net/quic/QUICPacket.h | 73 ++++--- iocore/net/quic/QUICTypes.cc | 1 + iocore/net/quic/test/test_QUICLossDetector.cc | 4 +- iocore/net/quic/test/test_QUICPacket.cc | 10 +- iocore/net/quic/test/test_QUICPacketFactory.cc | 6 +- iocore/net/quic/test/test_QUICVersionNegotiator.cc | 2 +- 16 files changed, 265 insertions(+), 161 deletions(-) diff --git a/iocore/net/P_QUICNetVConnection.h b/iocore/net/P_QUICNetVConnection.h index 8ee7cdf..02606ea 100644 --- a/iocore/net/P_QUICNetVConnection.h +++ b/iocore/net/P_QUICNetVConnection.h @@ -175,6 +175,8 @@ public: NetVConnectionContext_t direction() override; SSLNextProtocolSet *next_protocol_set() override; void close(QUICError error) override; + QUICPacketNumber largest_received_packet_number() override; + QUICPacketNumber largest_acked_packet_number() override; // QUICConnection (QUICPacketTransmitter) virtual void transmit_packet(std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet) override; @@ -190,8 +192,9 @@ public: private: QUICConnectionId _quic_connection_id; - UDPConnection *_udp_con = nullptr; - QUICPacketHandler *_packet_handler = nullptr; + QUICPacketNumber _largest_received_packet_number = 0; + UDPConnection *_udp_con = nullptr; + QUICPacketHandler *_packet_handler = nullptr; QUICPacketFactory _packet_factory; QUICFrameFactory _frame_factory; QUICAckFrameCreator _ack_frame_creator; diff --git a/iocore/net/P_QUICPacketHandler.h b/iocore/net/P_QUICPacketHandler.h index ce77b4a..c40f255 100644 --- a/iocore/net/P_QUICPacketHandler.h +++ b/iocore/net/P_QUICPacketHandler.h @@ -43,6 +43,7 @@ public: private: void _recv_packet(int event, UDPPacket *udpPacket); + bool _read_connection_id(QUICConnectionId &cid, IOBufferBlock *block); Map<int64_t, QUICNetVConnection *> _connections; SSL_CTX *_ssl_ctx; diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc index f5a15ba..8cf5763 100644 --- a/iocore/net/QUICNetVConnection.cc +++ b/iocore/net/QUICNetVConnection.cc @@ -232,7 +232,8 @@ QUICNetVConnection::get_transmitter_mutex() void QUICNetVConnection::push_packet(std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet) { - DebugQUICCon("Type=%s Size=%u", QUICDebugNames::packet_type(packet->type()), packet->size()); + DebugQUICCon("type=%s pkt_num=%" PRIu64 " size=%u", QUICDebugNames::packet_type(packet->type()), packet->packet_number(), + packet->size()); this->_packet_recv_queue.enqueue(const_cast<QUICPacket *>(packet.release())); } @@ -506,6 +507,18 @@ QUICNetVConnection::next_protocol_set() return this->_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(); +} + QUICError QUICNetVConnection::_state_handshake_process_initial_client_packet(std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet) { @@ -684,6 +697,10 @@ QUICNetVConnection::_packetize_frames() QUICError QUICNetVConnection::_recv_and_ack(const uint8_t *payload, uint16_t size, QUICPacketNumber packet_num) { + if (packet_num > this->_largest_received_packet_number) { + this->_largest_received_packet_number = packet_num; + } + bool should_send_ack; QUICError error; @@ -718,15 +735,16 @@ QUICNetVConnection::_build_packet(ats_unique_buf buf, size_t len, bool retransmi switch (type) { case QUICPacketType::SERVER_CLEARTEXT: - packet = this->_packet_factory.create_server_cleartext_packet(this->_quic_connection_id, std::move(buf), len, retransmittable); + packet = this->_packet_factory.create_server_cleartext_packet(this->_quic_connection_id, this->largest_acked_packet_number(), + std::move(buf), len, retransmittable); break; default: if (this->_handshake_handler && this->_handshake_handler->is_completed()) { - packet = - this->_packet_factory.create_server_protected_packet(this->_quic_connection_id, std::move(buf), len, retransmittable); + packet = this->_packet_factory.create_server_protected_packet(this->_quic_connection_id, this->largest_acked_packet_number(), + std::move(buf), len, retransmittable); } else { - packet = - this->_packet_factory.create_server_cleartext_packet(this->_quic_connection_id, std::move(buf), len, retransmittable); + packet = this->_packet_factory.create_server_cleartext_packet(this->_quic_connection_id, this->largest_acked_packet_number(), + std::move(buf), len, retransmittable); } break; } diff --git a/iocore/net/QUICPacketHandler.cc b/iocore/net/QUICPacketHandler.cc index 0a7278c..0531aeb 100644 --- a/iocore/net/QUICPacketHandler.cc +++ b/iocore/net/QUICPacketHandler.cc @@ -91,13 +91,42 @@ QUICPacketHandler::init_accept(EThread *t = nullptr) SET_HANDLER(&QUICPacketHandler::acceptEvent); } +// TODO: Integrate with QUICPacketHeader::connection_id() +bool +QUICPacketHandler::_read_connection_id(QUICConnectionId &cid, IOBufferBlock *block) +{ + const uint8_t *buf = reinterpret_cast<const uint8_t *>(block->buf()); + const uint8_t cid_offset = 1; + const uint8_t cid_len = 8; + + if (QUICTypeUtil::hasLongHeader(buf)) { + cid = QUICTypeUtil::read_QUICConnectionId(buf + cid_offset, cid_len); + } else { + if (buf[0] & 0x40) { + cid = QUICTypeUtil::read_QUICConnectionId(buf + cid_offset, cid_len); + } else { + return false; + } + } + + return true; +} + void QUICPacketHandler::_recv_packet(int event, UDPPacket *udpPacket) { IOBufferBlock *block = udpPacket->getIOBlockChain(); - std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> qPkt = QUICPacketFactory::create(block); - QUICNetVConnection *vc = this->_connections.get(qPkt->connection_id()); + QUICConnectionId cid; + bool res = this->_read_connection_id(cid, block); + + QUICNetVConnection *vc = nullptr; + if (res) { + vc = this->_connections.get(cid); + } else { + // TODO: find vc from five tuples + ink_assert(false); + } if (!vc) { // Unknown Connection ID @@ -119,9 +148,10 @@ QUICPacketHandler::_recv_packet(int event, UDPPacket *udpPacket) vc->options.ip_family = udpPacket->from.sa.sa_family; // TODO: Handle Connection ID of Client Cleartext / Non-Final Server Cleartext Packet - this->_connections.put(qPkt->connection_id(), vc); + this->_connections.put(cid, vc); } + std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> qPkt = QUICPacketFactory::create(block, vc->largest_received_packet_number()); vc->push_packet(std::move(qPkt)); // send to EThread diff --git a/iocore/net/quic/Mock.h b/iocore/net/quic/Mock.h index a9c4bf9..ddf056d 100644 --- a/iocore/net/quic/Mock.h +++ b/iocore/net/quic/Mock.h @@ -162,6 +162,18 @@ public: return 1280; } + QUICPacketNumber + largest_received_packet_number() override + { + return 0; + } + + QUICPacketNumber + largest_acked_packet_number() override + { + return 0; + } + NetVConnectionContext_t direction() override { diff --git a/iocore/net/quic/QUICConnection.h b/iocore/net/quic/QUICConnection.h index 0e571ed..8113ade 100644 --- a/iocore/net/quic/QUICConnection.h +++ b/iocore/net/quic/QUICConnection.h @@ -34,10 +34,12 @@ class SSLNextProtocolSet; class QUICConnection : public QUICPacketTransmitter, public QUICFrameTransmitter, public QUICFrameHandler { public: - virtual uint32_t maximum_quic_packet_size() = 0; - virtual uint32_t minimum_quic_packet_size() = 0; - virtual uint32_t pmtu() = 0; - virtual NetVConnectionContext_t direction() = 0; - virtual SSLNextProtocolSet *next_protocol_set() = 0; - virtual void close(QUICError error) = 0; + virtual uint32_t maximum_quic_packet_size() = 0; + virtual uint32_t minimum_quic_packet_size() = 0; + virtual uint32_t pmtu() = 0; + virtual NetVConnectionContext_t direction() = 0; + virtual SSLNextProtocolSet *next_protocol_set() = 0; + virtual void close(QUICError error) = 0; + virtual QUICPacketNumber largest_received_packet_number() = 0; + virtual QUICPacketNumber largest_acked_packet_number() = 0; }; diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc index 18beda7..85455fc 100644 --- a/iocore/net/quic/QUICHandshake.cc +++ b/iocore/net/quic/QUICHandshake.cc @@ -85,7 +85,8 @@ QUICHandshake::start(const QUICPacket *initial_packet, QUICPacketFactory *packet Debug(tag, "Version negotiation succeeded: %x", initial_packet->version()); packet_factory->set_version(this->_version_negotiator->negotiated_version()); } else { - this->_client_qc->transmit_packet(packet_factory->create_version_negotiation_packet(initial_packet)); + this->_client_qc->transmit_packet( + packet_factory->create_version_negotiation_packet(initial_packet, _client_qc->largest_acked_packet_number())); Debug(tag, "Version negotiation failed: %x", initial_packet->version()); } } else { diff --git a/iocore/net/quic/QUICLossDetector.cc b/iocore/net/quic/QUICLossDetector.cc index cd8fefd..feb48aa 100644 --- a/iocore/net/quic/QUICLossDetector.cc +++ b/iocore/net/quic/QUICLossDetector.cc @@ -96,6 +96,12 @@ QUICLossDetector::handle_frame(std::shared_ptr<const QUICFrame> frame) return error; } +QUICPacketNumber +QUICLossDetector::largest_acked_packet_number() +{ + return this->_largest_acked_packet; +} + void QUICLossDetector::_detect_lost_packets(QUICPacketNumber largest_acked_packet_number) { diff --git a/iocore/net/quic/QUICLossDetector.h b/iocore/net/quic/QUICLossDetector.h index b12a293..82bfa9b 100644 --- a/iocore/net/quic/QUICLossDetector.h +++ b/iocore/net/quic/QUICLossDetector.h @@ -48,6 +48,7 @@ public: std::vector<QUICFrameType> interests() override; virtual QUICError handle_frame(std::shared_ptr<const QUICFrame>) override; void on_packet_sent(std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet); + QUICPacketNumber largest_acked_packet_number(); private: struct PacketInfo { diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc index d009249..3ef847f 100644 --- a/iocore/net/quic/QUICPacket.cc +++ b/iocore/net/quic/QUICPacket.cc @@ -35,6 +35,9 @@ static constexpr int OFFSET_PAYLOAD = 17; static constexpr int LONGHEADER_LENGTH = 17; static constexpr int FNV1A_HASH_LEN = 8; +// +// QUICPacketHeader +// const uint8_t * QUICPacketHeader::buf() { @@ -42,58 +45,61 @@ QUICPacketHeader::buf() } QUICPacketHeader * -QUICPacketHeader::load(const uint8_t *buf, size_t len) +QUICPacketHeader::load(const uint8_t *buf, size_t len, QUICPacketNumber base) { if (QUICTypeUtil::hasLongHeader(buf)) { QUICPacketLongHeader *long_header = quicPacketLongHeaderAllocator.alloc(); - new (long_header) QUICPacketLongHeader(buf, len); + new (long_header) QUICPacketLongHeader(buf, len, base); return long_header; } else { QUICPacketShortHeader *short_header = quicPacketShortHeaderAllocator.alloc(); - new (short_header) QUICPacketShortHeader(buf, len); + new (short_header) QUICPacketShortHeader(buf, len, base); return short_header; } } QUICPacketHeader * -QUICPacketHeader::build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, QUICVersion version, - ats_unique_buf payload, size_t len) +QUICPacketHeader::build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf payload, size_t len) { QUICPacketLongHeader *long_header = quicPacketLongHeaderAllocator.alloc(); - new (long_header) QUICPacketLongHeader(type, connection_id, packet_number, version, std::move(payload), len); + new (long_header) QUICPacketLongHeader(type, connection_id, packet_number, base_packet_number, version, std::move(payload), len); return long_header; } QUICPacketHeader * -QUICPacketHeader::build(QUICPacketType type, QUICPacketNumber packet_number, ats_unique_buf payload, size_t len) +QUICPacketHeader::build(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, + ats_unique_buf payload, size_t len) { QUICPacketShortHeader *short_header = quicPacketShortHeaderAllocator.alloc(); - new (short_header) QUICPacketShortHeader(type, packet_number, std::move(payload), len); + new (short_header) QUICPacketShortHeader(type, packet_number, base_packet_number, std::move(payload), len); return short_header; } QUICPacketHeader * -QUICPacketHeader::build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, ats_unique_buf payload, - size_t len) +QUICPacketHeader::build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len) { QUICPacketShortHeader *short_header = quicPacketShortHeaderAllocator.alloc(); - new (short_header) QUICPacketShortHeader(type, connection_id, packet_number, std::move(payload), len); + new (short_header) QUICPacketShortHeader(type, connection_id, packet_number, base_packet_number, std::move(payload), len); return short_header; } +// // QUICPacketLongHeader - +// QUICPacketLongHeader::QUICPacketLongHeader(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, - QUICVersion version, ats_unique_buf buf, size_t len) + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf buf, size_t len) { - this->_type = type; - this->_has_connection_id = true; - this->_connection_id = connection_id; - this->_packet_number = packet_number; - this->_has_version = true; - this->_version = version; - this->_payload = std::move(buf); - this->_payload_len = len; + this->_type = type; + this->_has_connection_id = true; + this->_connection_id = connection_id; + this->_packet_number = packet_number; + this->_base_packet_number = base_packet_number; + this->_has_version = true; + this->_version = version; + this->_payload = std::move(buf); + this->_payload_len = len; } QUICPacketType @@ -125,7 +131,12 @@ QUICPacketNumber QUICPacketLongHeader::packet_number() const { if (this->_buf) { - return QUICTypeUtil::read_QUICPacketNumber(this->_buf + OFFSET_PACKET_NUMBER, 4); + const uint8_t packet_number_len = 4; + QUICPacketNumber src = QUICTypeUtil::read_QUICPacketNumber(this->_buf + OFFSET_PACKET_NUMBER, packet_number_len); + QUICPacketNumber dst = 0; + QUICPacket::decode_packet_number(dst, src, packet_number_len, this->_base_packet_number); + + return dst; } else { return this->_packet_number; } @@ -191,21 +202,30 @@ QUICPacketLongHeader::store(uint8_t *buf, size_t *len) const *len += 1; QUICTypeUtil::write_QUICConnectionId(this->_connection_id, 8, buf + *len, &n); *len += n; - QUICTypeUtil::write_QUICPacketNumber(this->_packet_number, 4, buf + *len, &n); + + QUICPacketNumber dst = 0; + size_t dst_len = 4; + QUICPacket::encode_packet_number(dst, this->_packet_number, dst_len); + QUICTypeUtil::write_QUICPacketNumber(dst, dst_len, buf + *len, &n); *len += n; + QUICTypeUtil::write_QUICVersion(this->_version, buf + *len, &n); *len += n; } +// // QUICPacketShortHeader - -QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICPacketNumber packet_number, ats_unique_buf buf, size_t len) +// +QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, ats_unique_buf buf, size_t len) { - this->_type = type; - this->_has_key_phase = true; - this->_packet_number = packet_number; - this->_payload = std::move(buf); - this->_payload_len = len; + this->_type = type; + this->_has_key_phase = true; + this->_packet_number = packet_number; + this->_base_packet_number = base_packet_number; + this->_packet_number_type = this->_discover_packet_number_type(packet_number, base_packet_number); + this->_payload = std::move(buf); + this->_payload_len = len; if (type == QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0) { this->_key_phase = QUICKeyPhase::PHASE_0; @@ -215,26 +235,20 @@ QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICPacketNumb ink_assert(false); this->_key_phase = QUICKeyPhase::PHASE_UNINITIALIZED; } - - if (packet_number <= 0xFF) { - this->_packet_number_type = QUICPacketShortHeaderType::ONE; - } else if (packet_number <= 0xFFFF) { - this->_packet_number_type = QUICPacketShortHeaderType::TWO; - } else { - this->_packet_number_type = QUICPacketShortHeaderType::THREE; - } } QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, - ats_unique_buf buf, size_t len) -{ - this->_type = type; - this->_has_key_phase = true; - this->_has_connection_id = true; - this->_connection_id = connection_id; - this->_packet_number = packet_number; - this->_payload = std::move(buf); - this->_payload_len = len; + QUICPacketNumber base_packet_number, ats_unique_buf buf, size_t len) +{ + this->_type = type; + this->_has_key_phase = true; + this->_has_connection_id = true; + this->_connection_id = connection_id; + this->_packet_number = packet_number; + this->_base_packet_number = base_packet_number; + this->_packet_number_type = this->_discover_packet_number_type(packet_number, base_packet_number); + this->_payload = std::move(buf); + this->_payload_len = len; if (type == QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0) { this->_key_phase = QUICKeyPhase::PHASE_0; @@ -244,14 +258,6 @@ QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICConnection ink_assert(false); this->_key_phase = QUICKeyPhase::PHASE_UNINITIALIZED; } - - if (packet_number <= 0xFF) { - this->_packet_number_type = QUICPacketShortHeaderType::ONE; - } else if (packet_number <= 0xFFFF) { - this->_packet_number_type = QUICPacketShortHeaderType::TWO; - } else { - this->_packet_number_type = QUICPacketShortHeaderType::THREE; - } } QUICPacketType @@ -287,13 +293,17 @@ QUICPacketNumber QUICPacketShortHeader::packet_number() const { if (this->_buf) { - int n = this->_packet_numberLen(); + int n = this->_packet_number_len(); int offset = 1; if (this->has_connection_id()) { offset = OFFSET_PACKET_NUMBER; } - return QUICTypeUtil::read_QUICPacketNumber(this->_buf + offset, n); + QUICPacketNumber src = QUICTypeUtil::read_QUICPacketNumber(this->_buf + offset, n); + QUICPacketNumber dst = 0; + QUICPacket::decode_packet_number(dst, src, n, this->_base_packet_number); + + return dst; } else { return this->_packet_number; } @@ -312,7 +322,7 @@ QUICPacketShortHeader::version() const } int -QUICPacketShortHeader::_packet_numberLen() const +QUICPacketShortHeader::_packet_number_len() const { QUICPacketShortHeaderType type; if (this->_buf) { @@ -334,6 +344,20 @@ QUICPacketShortHeader::_packet_numberLen() const } } +QUICPacketShortHeaderType +QUICPacketShortHeader::_discover_packet_number_type(QUICPacketNumber packet_number, QUICPacketNumber base_packet_number) const +{ + uint64_t d = (packet_number - base_packet_number) * 2; + + if (d > 0xFFFF) { + return QUICPacketShortHeaderType::THREE; + } else if (d > 0xFF) { + return QUICPacketShortHeaderType::TWO; + } else { + return QUICPacketShortHeaderType::ONE; + } +} + bool QUICPacketShortHeader::has_connection_id() const { @@ -385,7 +409,7 @@ QUICPacketShortHeader::length() const if (this->has_connection_id()) { len += 8; } - len += this->_packet_numberLen(); + len += this->_packet_number_len(); return len; } @@ -408,34 +432,30 @@ QUICPacketShortHeader::store(uint8_t *buf, size_t *len) const QUICTypeUtil::write_QUICConnectionId(this->_connection_id, 8, buf + *len, &n); *len += n; } - switch (this->_packet_number_type) { - case QUICPacketShortHeaderType::ONE: - QUICTypeUtil::write_QUICPacketNumber(this->_packet_number, 1, buf + *len, &n); - break; - case QUICPacketShortHeaderType::TWO: - QUICTypeUtil::write_QUICPacketNumber(this->_packet_number, 2, buf + *len, &n); - break; - case QUICPacketShortHeaderType::THREE: - QUICTypeUtil::write_QUICPacketNumber(this->_packet_number, 4, buf + *len, &n); - break; - default: - ink_release_assert(0); - } + + QUICPacketNumber dst = 0; + size_t dst_len = this->_packet_number_len(); + QUICPacket::encode_packet_number(dst, this->_packet_number, dst_len); + QUICTypeUtil::write_QUICPacketNumber(dst, dst_len, buf + *len, &n); + *len += n; } +// // QUICPacket - -QUICPacket::QUICPacket(IOBufferBlock *block) : _block(block) +// +QUICPacket::QUICPacket(IOBufferBlock *block, QUICPacketNumber base_packet_number) : _block(block) { - this->_size = block->size(); - this->_header = QUICPacketHeader::load(reinterpret_cast<const uint8_t *>(this->_block->buf()), this->_block->size()); + this->_size = block->size(); + this->_header = + QUICPacketHeader::load(reinterpret_cast<const uint8_t *>(this->_block->buf()), this->_block->size(), base_packet_number); } -QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, QUICVersion version, - ats_unique_buf payload, size_t len, bool retransmittable) +QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf payload, size_t len, + bool retransmittable) { - this->_header = QUICPacketHeader::build(type, connection_id, packet_number, version, std::move(payload), len); + this->_header = QUICPacketHeader::build(type, connection_id, packet_number, base_packet_number, version, std::move(payload), len); this->_size = this->_header->length() + len; if (type != QUICPacketType::ZERO_RTT_PROTECTED && type != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && type != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { @@ -444,10 +464,10 @@ QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUIC this->_is_retransmittable = retransmittable; } -QUICPacket::QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, ats_unique_buf payload, size_t len, - bool retransmittable) +QUICPacket::QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, + ats_unique_buf payload, size_t len, bool retransmittable) { - this->_header = QUICPacketHeader::build(type, packet_number, std::move(payload), len); + this->_header = QUICPacketHeader::build(type, packet_number, base_packet_number, std::move(payload), len); this->_size = this->_header->length() + len; if (type != QUICPacketType::ZERO_RTT_PROTECTED && type != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && type != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { @@ -456,10 +476,10 @@ QUICPacket::QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, ats_ this->_is_retransmittable = retransmittable; } -QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, ats_unique_buf payload, - size_t len, bool retransmittable) +QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len, bool retransmittable) { - this->_header = QUICPacketHeader::build(type, connection_id, packet_number, std::move(payload), len); + this->_header = QUICPacketHeader::build(type, connection_id, packet_number, base_packet_number, std::move(payload), len); this->_size = this->_header->length() + len; if (type != QUICPacketType::ZERO_RTT_PROTECTED && type != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && type != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { @@ -646,15 +666,15 @@ QUICPacket::decode_packet_number(QUICPacketNumber &dst, QUICPacketNumber src, si // QUICPacketFactory // std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> -QUICPacketFactory::create(IOBufferBlock *block) +QUICPacketFactory::create(IOBufferBlock *block, QUICPacketNumber base_packet_number) { QUICPacket *packet = quicPacketAllocator.alloc(); - new (packet) QUICPacket(block); + new (packet) QUICPacket(block, base_packet_number); return std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(packet, &QUICPacketDeleter::delete_packet); } std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> -QUICPacketFactory::create_version_negotiation_packet(const QUICPacket *packet_sent_by_client) +QUICPacketFactory::create_version_negotiation_packet(const QUICPacket *packet_sent_by_client, QUICPacketNumber base_packet_number) { size_t len = sizeof(QUICVersion) * countof(QUIC_SUPPORTED_VERSIONS); ats_unique_buf versions(reinterpret_cast<uint8_t *>(ats_malloc(len)), [](void *p) { ats_free(p); }); @@ -669,28 +689,28 @@ QUICPacketFactory::create_version_negotiation_packet(const QUICPacket *packet_se QUICPacket *packet = quicPacketAllocator.alloc(); new (packet) QUICPacket(QUICPacketType::VERSION_NEGOTIATION, packet_sent_by_client->connection_id(), packet_sent_by_client->packet_number(), - packet_sent_by_client->version(), std::move(versions), len, false); + base_packet_number, packet_sent_by_client->version(), std::move(versions), len, false); return std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(packet, QUICPacketDeleter::delete_packet); } std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> -QUICPacketFactory::create_server_cleartext_packet(QUICConnectionId connection_id, ats_unique_buf payload, size_t len, - bool retransmittable) +QUICPacketFactory::create_server_cleartext_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number, + ats_unique_buf payload, size_t len, bool retransmittable) { QUICPacket *p = quicPacketAllocator.alloc(); - new (p) QUICPacket(QUICPacketType::SERVER_CLEARTEXT, connection_id, this->_packet_number_generator.next(), this->_version, - std::move(payload), len, retransmittable); + new (p) QUICPacket(QUICPacketType::SERVER_CLEARTEXT, connection_id, this->_packet_number_generator.next(), base_packet_number, + this->_version, std::move(payload), len, retransmittable); return std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(p, &QUICPacketDeleter::delete_packet); } std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> -QUICPacketFactory::create_server_protected_packet(QUICConnectionId connection_id, ats_unique_buf payload, size_t len, - bool retransmittable) +QUICPacketFactory::create_server_protected_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number, + ats_unique_buf payload, size_t len, bool retransmittable) { // TODO Key phase should be picked up from QUICCrypto, probably QUICPacket *p = quicPacketAllocator.alloc(); new (p) QUICPacket(QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0, connection_id, this->_packet_number_generator.next(), - std::move(payload), len, retransmittable); + base_packet_number, std::move(payload), len, retransmittable); auto packet = std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(p, &QUICPacketDeleter::delete_packet); // TODO: use pmtu of UnixNetVConnection @@ -716,12 +736,12 @@ QUICPacketFactory::create_server_protected_packet(QUICConnectionId connection_id } std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> -QUICPacketFactory::create_client_initial_packet(QUICConnectionId connection_id, QUICVersion version, ats_unique_buf payload, - size_t len) +QUICPacketFactory::create_client_initial_packet(QUICConnectionId connection_id, QUICPacketNumber base_packet_number, + QUICVersion version, ats_unique_buf payload, size_t len) { QUICPacket *packet = quicPacketAllocator.alloc(); - new (packet) QUICPacket(QUICPacketType::CLIENT_INITIAL, connection_id, this->_packet_number_generator.next(), version, - std::move(payload), len, true); + new (packet) QUICPacket(QUICPacketType::CLIENT_INITIAL, connection_id, this->_packet_number_generator.next(), base_packet_number, + version, std::move(payload), len, true); return std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(packet, &QUICPacketDeleter::delete_packet); } diff --git a/iocore/net/quic/QUICPacket.h b/iocore/net/quic/QUICPacket.h index 02ecf66..326a348 100644 --- a/iocore/net/quic/QUICPacket.h +++ b/iocore/net/quic/QUICPacket.h @@ -39,7 +39,7 @@ class QUICPacketHeader { public: - QUICPacketHeader(const uint8_t *buf, size_t len) : _buf(buf) {} + QUICPacketHeader(const uint8_t *buf, size_t len, QUICPacketNumber base) : _buf(buf), _base_packet_number(base) {} const uint8_t *buf(); virtual QUICPacketType type() const = 0; virtual QUICConnectionId connection_id() const = 0; @@ -49,12 +49,13 @@ public: virtual QUICKeyPhase key_phase() const = 0; virtual uint16_t length() const = 0; virtual void store(uint8_t *buf, size_t *len) const = 0; - static QUICPacketHeader *load(const uint8_t *buf, size_t len); - static QUICPacketHeader *build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, - QUICVersion version, ats_unique_buf payload, size_t len); - static QUICPacketHeader *build(QUICPacketType type, QUICPacketNumber packet_number, ats_unique_buf payload, size_t len); + static QUICPacketHeader *load(const uint8_t *buf, size_t len, QUICPacketNumber base); static QUICPacketHeader *build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf payload, size_t len); + static QUICPacketHeader *build(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len); + static QUICPacketHeader *build(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len); virtual bool has_key_phase() const = 0; virtual bool has_connection_id() const = 0; virtual bool has_version() const = 0; @@ -62,26 +63,27 @@ public: protected: QUICPacketHeader(){}; - const uint8_t *_buf = nullptr; - ats_unique_buf _payload = ats_unique_buf(nullptr, [](void *p) { ats_free(p); }); - QUICPacketType _type = QUICPacketType::UNINITIALIZED; - QUICKeyPhase _key_phase = QUICKeyPhase::PHASE_UNINITIALIZED; - QUICConnectionId _connection_id = 0; - QUICPacketNumber _packet_number = 0; - QUICVersion _version = 0; - size_t _payload_len = 0; - bool _has_key_phase = false; - bool _has_connection_id = false; - bool _has_version = false; + const uint8_t *_buf = nullptr; + ats_unique_buf _payload = ats_unique_buf(nullptr, [](void *p) { ats_free(p); }); + QUICPacketType _type = QUICPacketType::UNINITIALIZED; + QUICKeyPhase _key_phase = QUICKeyPhase::PHASE_UNINITIALIZED; + QUICConnectionId _connection_id = 0; + QUICPacketNumber _packet_number = 0; + QUICPacketNumber _base_packet_number = 0; + QUICVersion _version = 0; + size_t _payload_len = 0; + bool _has_key_phase = false; + bool _has_connection_id = false; + bool _has_version = false; }; class QUICPacketLongHeader : public QUICPacketHeader { public: QUICPacketLongHeader() : QUICPacketHeader(){}; - QUICPacketLongHeader(const uint8_t *buf, size_t len) : QUICPacketHeader(buf, len) {} - QUICPacketLongHeader(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, QUICVersion version, - ats_unique_buf buf, size_t len); + QUICPacketLongHeader(const uint8_t *buf, size_t len, QUICPacketNumber base) : QUICPacketHeader(buf, len, base) {} + QUICPacketLongHeader(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf buf, size_t len); QUICPacketType type() const; QUICConnectionId connection_id() const; QUICPacketNumber packet_number() const; @@ -99,10 +101,11 @@ class QUICPacketShortHeader : public QUICPacketHeader { public: QUICPacketShortHeader() : QUICPacketHeader(){}; - QUICPacketShortHeader(const uint8_t *buf, size_t len) : QUICPacketHeader(buf, len) {} - QUICPacketShortHeader(QUICPacketType type, QUICPacketNumber packet_number, ats_unique_buf buf, size_t len); - QUICPacketShortHeader(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, ats_unique_buf buf, - size_t len); + QUICPacketShortHeader(const uint8_t *buf, size_t len, QUICPacketNumber base) : QUICPacketHeader(buf, len, base) {} + QUICPacketShortHeader(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, + ats_unique_buf buf, size_t len); + QUICPacketShortHeader(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, ats_unique_buf buf, size_t len); QUICPacketType type() const; QUICConnectionId connection_id() const; QUICPacketNumber packet_number() const; @@ -116,7 +119,8 @@ public: void store(uint8_t *buf, size_t *len) const; private: - int _packet_numberLen() const; + QUICPacketShortHeaderType _discover_packet_number_type(QUICPacketNumber packet_number, QUICPacketNumber base_packet_number) const; + int _packet_number_len() const; QUICPacketShortHeaderType _packet_number_type = QUICPacketShortHeaderType::UNINITIALIZED; }; @@ -124,12 +128,13 @@ class QUICPacket { public: QUICPacket(){}; - QUICPacket(IOBufferBlock *block); - QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, QUICVersion version, - ats_unique_buf payload, size_t len, bool retransmittable); - QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, ats_unique_buf payload, size_t len, bool retransmittable); - QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, ats_unique_buf payload, - size_t len, bool retransmittabl); + QUICPacket(IOBufferBlock *block, QUICPacketNumber base_packet_number); + QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf payload, size_t len, bool retransmittable); + QUICPacket(QUICPacketType type, QUICPacketNumber packet_number, QUICPacketNumber base_packet_number, ats_unique_buf payload, + size_t len, bool retransmittable); + QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICPacketNumber packet_number, + QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len, bool retransmittabl); ~QUICPacket(); void set_protected_payload(ats_unique_buf cipher_txt, size_t cipher_txt_len); @@ -197,15 +202,19 @@ public: class QUICPacketFactory { public: - static std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create(IOBufferBlock *block); - std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create_version_negotiation_packet(const QUICPacket *packet_sent_by_client); + static std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create(IOBufferBlock *block, QUICPacketNumber base_packet_number); + std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create_version_negotiation_packet(const QUICPacket *packet_sent_by_client, + QUICPacketNumber base_packet_number); std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create_server_cleartext_packet(QUICConnectionId connection_id, + QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len, bool retransmittable); std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create_server_protected_packet(QUICConnectionId connection_id, + QUICPacketNumber base_packet_number, ats_unique_buf payload, size_t len, bool retransmittable); std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create_client_initial_packet(QUICConnectionId connection_id, + QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf payload, size_t len); void set_version(QUICVersion negotiated_version); diff --git a/iocore/net/quic/QUICTypes.cc b/iocore/net/quic/QUICTypes.cc index e77f71f..f0cca15 100644 --- a/iocore/net/quic/QUICTypes.cc +++ b/iocore/net/quic/QUICTypes.cc @@ -40,6 +40,7 @@ QUICTypeUtil::hasLongHeader(const uint8_t *buf) QUICConnectionId QUICTypeUtil::read_QUICConnectionId(const uint8_t *buf, uint8_t len) { + // Should be QUICConnectionId(read_nbytes_as_uint(buf, len)); return static_cast<QUICPacketNumber>(read_nbytes_as_uint(buf, len)); } diff --git a/iocore/net/quic/test/test_QUICLossDetector.cc b/iocore/net/quic/test/test_QUICLossDetector.cc index b23e156..e77670d 100644 --- a/iocore/net/quic/test/test_QUICLossDetector.cc +++ b/iocore/net/quic/test/test_QUICLossDetector.cc @@ -41,8 +41,8 @@ TEST_CASE("QUICLossDetector_Loss_in_Handshake", "[quic]") memcpy(payload.get(), raw, sizeof(raw)); std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet = std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>( - new QUICPacket(QUICPacketType::SERVER_CLEARTEXT, 0xffddbb9977553311ULL, 0x00000001, 0x00112233, std::move(payload), sizeof(raw), - true), + new QUICPacket(QUICPacketType::SERVER_CLEARTEXT, 0xffddbb9977553311ULL, 0x00000001, 0, 0x00112233, std::move(payload), + sizeof(raw), true), [](QUICPacket *p) { delete p; }); detector.on_packet_sent(std::move(packet)); ink_hrtime_sleep(HRTIME_MSECONDS(1000)); diff --git a/iocore/net/quic/test/test_QUICPacket.cc b/iocore/net/quic/test/test_QUICPacket.cc index 82a6632..a987004 100644 --- a/iocore/net/quic/test/test_QUICPacket.cc +++ b/iocore/net/quic/test/test_QUICPacket.cc @@ -32,7 +32,7 @@ TEST_CASE("Loading Long Header Packet", "[quic]") memcpy(payload.get(), raw, sizeof(raw)); // Cleartext packet with a long header - QUICPacket packet1(QUICPacketType::CLIENT_CLEARTEXT, 0xffddbb9977553311ULL, 0xffcc9966, 0x00112233, std::move(payload), + QUICPacket packet1(QUICPacketType::CLIENT_CLEARTEXT, 0xffddbb9977553311ULL, 0xffcc9966, 0, 0x00112233, std::move(payload), sizeof(raw), true); uint8_t buf[65536]; @@ -44,7 +44,7 @@ TEST_CASE("Loading Long Header Packet", "[quic]") memcpy(block->end(), buf, len); block->fill(len); - const QUICPacket packet2(block); + const QUICPacket packet2(block, 0); CHECK(packet2.type() == QUICPacketType::CLIENT_CLEARTEXT); CHECK(packet2.connection_id() == 0xffddbb9977553311ULL); @@ -66,7 +66,7 @@ TEST_CASE("Loading Short Header Packet", "[quic]") memcpy(protected_payload.get(), protected_raw, sizeof(protected_raw)); // Cleartext packet with a long header - QUICPacket packet1(QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0, 0xffcc9966, std::move(payload), sizeof(raw), true); + QUICPacket packet1(QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0, 0xffcc9966, 0, std::move(payload), sizeof(raw), true); packet1.set_protected_payload(std::move(protected_payload), sizeof(protected_raw)); uint8_t buf[65536]; @@ -78,7 +78,7 @@ TEST_CASE("Loading Short Header Packet", "[quic]") memcpy(block->end(), buf, len); block->fill(len); - const QUICPacket packet2(block); + const QUICPacket packet2(block, 0); CHECK(packet2.type() == QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0); CHECK(packet2.packet_number() == 0xffcc9966); @@ -90,7 +90,7 @@ TEST_CASE("Loading Short Header Packet", "[quic]") TEST_CASE("Loading Unknown Packet", "[quic]") { const uint8_t buf[] = {0xff}; - QUICPacketHeader *header = QUICPacketHeader::load(buf, sizeof(buf)); + QUICPacketHeader *header = QUICPacketHeader::load(buf, sizeof(buf), 0); CHECK(header->type() == QUICPacketType::UNINITIALIZED); } diff --git a/iocore/net/quic/test/test_QUICPacketFactory.cc b/iocore/net/quic/test/test_QUICPacketFactory.cc index 51850ff..b92144b 100644 --- a/iocore/net/quic/test/test_QUICPacketFactory.cc +++ b/iocore/net/quic/test/test_QUICPacketFactory.cc @@ -42,9 +42,9 @@ TEST_CASE("QUICPacketFactory_Create_VersionNegotiationPacket", "[quic]") memcpy(block->end(), client_initial_packet_data, sizeof(client_initial_packet_data)); block->fill(sizeof(client_initial_packet_data)); - QUICPacket client_initial_packet(block); + QUICPacket client_initial_packet(block, 0); - std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet = factory.create_version_negotiation_packet(&client_initial_packet); + std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet = factory.create_version_negotiation_packet(&client_initial_packet, 0); CHECK(packet->type() == QUICPacketType::VERSION_NEGOTIATION); CHECK(packet->connection_id() == client_initial_packet.connection_id()); CHECK(packet->packet_number() == client_initial_packet.packet_number()); @@ -61,7 +61,7 @@ TEST_CASE("QUICPacketFactory_Create_ServerCleartextPacket", "[quic]") memcpy(payload.get(), raw, sizeof(raw)); std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet = - factory.create_server_cleartext_packet(0x01020304, std::move(payload), sizeof(raw), true); + factory.create_server_cleartext_packet(0x01020304, 0, std::move(payload), sizeof(raw), true); CHECK(packet->type() == QUICPacketType::SERVER_CLEARTEXT); CHECK(packet->connection_id() == 0x01020304); CHECK(memcmp(packet->payload(), raw, sizeof(raw)) == 0); diff --git a/iocore/net/quic/test/test_QUICVersionNegotiator.cc b/iocore/net/quic/test/test_QUICVersionNegotiator.cc index 9de0bdb..1802c63 100644 --- a/iocore/net/quic/test/test_QUICVersionNegotiator.cc +++ b/iocore/net/quic/test/test_QUICVersionNegotiator.cc @@ -36,7 +36,7 @@ TEST_CASE("QUICVersionNegotiator_Normal", "[quic]") // Negotiate version std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> initial_packet = - packet_factory.create_client_initial_packet({}, QUIC_SUPPORTED_VERSIONS[0], ats_unique_malloc(0), 0); + packet_factory.create_client_initial_packet({}, 0, QUIC_SUPPORTED_VERSIONS[0], ats_unique_malloc(0), 0); vn.negotiate(initial_packet.get()); CHECK(vn.status() == QUICVersionNegotiationStatus::NEGOTIATED); -- To stop receiving notification emails like this one, please contact ['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].