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 34c9253 Add create_stateless_reset_packet 34c9253 is described below commit 34c9253dc403af84ed3938414f26bfaa05cc5d0b Author: Masakazu Kitajo <mas...@apache.org> AuthorDate: Tue Sep 12 11:21:35 2017 +0900 Add create_stateless_reset_packet --- iocore/net/QUICNetVConnection.cc | 2 +- iocore/net/quic/QUICDebugNames.cc | 4 +-- iocore/net/quic/QUICHandshake.cc | 4 +-- iocore/net/quic/QUICHandshake.h | 4 +-- iocore/net/quic/QUICPacket.cc | 45 ++++++++++++++++++++++---- iocore/net/quic/QUICPacket.h | 4 +++ iocore/net/quic/QUICTransportParameters.cc | 2 +- iocore/net/quic/QUICTransportParameters.h | 2 +- iocore/net/quic/QUICTypes.h | 14 +++++--- iocore/net/quic/test/test_QUICPacketFactory.cc | 28 ++++++++++++++++ 10 files changed, 90 insertions(+), 19 deletions(-) diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc index 3babca6..9cb85fa 100644 --- a/iocore/net/QUICNetVConnection.cc +++ b/iocore/net/QUICNetVConnection.cc @@ -98,7 +98,7 @@ QUICNetVConnection::start(SSL_CTX *ssl_ctx) // Version 0x00000001 uses stream 0 for cryptographic handshake with TLS 1.3, but newer version may not this->_token.gen_token(STATELESS_RETRY_TOKEN_KEY, _quic_connection_id ^ id); - this->_handshake_handler = new QUICHandshake(this, ssl_ctx, this->_token.get()); + this->_handshake_handler = new QUICHandshake(this, ssl_ctx, this->_token); this->_application_map = new QUICApplicationMap(); this->_application_map->set(STREAM_ID_FOR_HANDSHAKE, this->_handshake_handler); diff --git a/iocore/net/quic/QUICDebugNames.cc b/iocore/net/quic/QUICDebugNames.cc index 2f79b92..a6b359e 100644 --- a/iocore/net/quic/QUICDebugNames.cc +++ b/iocore/net/quic/QUICDebugNames.cc @@ -44,8 +44,8 @@ QUICDebugNames::packet_type(QUICPacketType type) return "ONE_RTT_PROTECTED_KEY_PHASE_0"; case QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1: return "ONE_RTT_PROTECTED_KEY_PHASE_1"; - case QUICPacketType::PUBLIC_RESET: - return "PUBLIC_RESET"; + case QUICPacketType::STATELESS_RESET: + return "STATELESS_RESET"; case QUICPacketType::UNINITIALIZED: default: return "UNKNOWN"; diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc index 9a2584d..daa47aa 100644 --- a/iocore/net/quic/QUICHandshake.cc +++ b/iocore/net/quic/QUICHandshake.cc @@ -54,7 +54,7 @@ static constexpr int UDP_MAXIMUM_PAYLOAD_SIZE = 65527; // TODO: fix size static constexpr int MAX_HANDSHAKE_MSG_LEN = 65527; -QUICHandshake::QUICHandshake(QUICConnection *qc, SSL_CTX *ssl_ctx, INK_MD5 token) : QUICApplication(qc), _token(token) +QUICHandshake::QUICHandshake(QUICConnection *qc, SSL_CTX *ssl_ctx, QUICStatelessToken token) : QUICApplication(qc), _token(token) { this->_ssl = SSL_new(ssl_ctx); SSL_set_ex_data(this->_ssl, QUIC::ssl_quic_qc_index, qc); @@ -258,7 +258,7 @@ QUICHandshake::_load_local_transport_parameters() params->no_activity_timeout_in(), sizeof(uint16_t)))); tp->add(QUICTransportParameterId::STATELESS_RETRY_TOKEN, - std::unique_ptr<QUICTransportParameterValue>(new QUICTransportParameterValue(this->_token.u64, 16))); + std::unique_ptr<QUICTransportParameterValue>(new QUICTransportParameterValue(this->_token.get_u64(), 16))); tp->add_version(QUIC_SUPPORTED_VERSIONS[0]); // MAYs diff --git a/iocore/net/quic/QUICHandshake.h b/iocore/net/quic/QUICHandshake.h index e8866d6..5d0060a 100644 --- a/iocore/net/quic/QUICHandshake.h +++ b/iocore/net/quic/QUICHandshake.h @@ -50,7 +50,7 @@ class SSLNextProtocolSet; class QUICHandshake : public QUICApplication { public: - QUICHandshake(QUICConnection *qc, SSL_CTX *ssl_ctx, INK_MD5 token); + QUICHandshake(QUICConnection *qc, SSL_CTX *ssl_ctx, QUICStatelessToken token); ~QUICHandshake(); QUICError start(const QUICPacket *initial_packet, QUICPacketFactory *packet_factory); @@ -88,5 +88,5 @@ private: QUICError _process_client_finished(); QUICError _process_handshake_complete(); - INK_MD5 _token; + QUICStatelessToken _token; }; diff --git a/iocore/net/quic/QUICPacket.cc b/iocore/net/quic/QUICPacket.cc index bfae22b..97e62c6 100644 --- a/iocore/net/quic/QUICPacket.cc +++ b/iocore/net/quic/QUICPacket.cc @@ -254,6 +254,8 @@ QUICPacketShortHeader::QUICPacketShortHeader(QUICPacketType type, QUICConnection this->_key_phase = QUICKeyPhase::PHASE_0; } else if (type == QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { this->_key_phase = QUICKeyPhase::PHASE_1; + } else if (type == QUICPacketType::STATELESS_RESET) { + this->_key_phase = QUICKeyPhase::PHASE_UNINITIALIZED; } else { ink_assert(false); this->_key_phase = QUICKeyPhase::PHASE_UNINITIALIZED; @@ -273,8 +275,7 @@ QUICPacketShortHeader::type() const return QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1; } default: - ink_assert(false); - return QUICPacketType::UNINITIALIZED; + return QUICPacketType::STATELESS_RESET; } } @@ -488,6 +489,25 @@ QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUIC this->_is_retransmittable = retransmittable; } +QUICPacket::QUICPacket(QUICPacketType type, QUICConnectionId connection_id, QUICStatelessToken stateless_reset_token) +{ + const uint8_t *token = stateless_reset_token.get_u8(); + QUICPacketNumber fake_packet_number = token[0]; + QUICPacketNumber fake_base_packet_number = token[0]; + ats_unique_buf fake_payload = ats_unique_malloc(15 + 8); + memcpy(fake_payload.get(), token + 1, 15); + // Append random bytes + std::random_device rnd; + for (int i = 15; i < 23; ++i) { + fake_payload.get()[i] = rnd() & 0xFF; + } + + this->_header = + QUICPacketHeader::build(type, connection_id, fake_packet_number, fake_base_packet_number, std::move(fake_payload), 15 + 8); + this->_size = this->_header->length() + 15 + 8; + this->_is_retransmittable = false; +} + QUICPacket::~QUICPacket() { if (this->_header->has_version()) { @@ -559,8 +579,10 @@ uint16_t QUICPacket::payload_size() const { // FIXME Protected packets may / may not contain something at the end - if (this->type() != QUICPacketType::ZERO_RTT_PROTECTED && this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && - this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { + if (this->type() == QUICPacketType::STATELESS_RESET) { + return this->_size - this->_header->length(); + } else if (this->type() != QUICPacketType::ZERO_RTT_PROTECTED && this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && + this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { return this->_size - this->_header->length() - FNV1A_HASH_LEN; } else { return this->_size - this->_header->length(); @@ -579,8 +601,11 @@ QUICPacket::store(uint8_t *buf, size_t *len) const this->_header->store(buf, len); ink_assert(this->size() >= *len); - if (this->type() != QUICPacketType::ZERO_RTT_PROTECTED && this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && - this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { + if (this->type() == QUICPacketType::STATELESS_RESET) { + memcpy(buf + *len, this->payload(), this->payload_size()); + *len += this->payload_size(); + } else if (this->type() != QUICPacketType::ZERO_RTT_PROTECTED && this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_0 && + this->type() != QUICPacketType::ONE_RTT_PROTECTED_KEY_PHASE_1) { memcpy(buf + *len, this->payload(), this->payload_size()); *len += this->payload_size(); @@ -745,6 +770,14 @@ QUICPacketFactory::create_client_initial_packet(QUICConnectionId connection_id, return std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(packet, &QUICPacketDeleter::delete_packet); } +std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> +QUICPacketFactory::create_stateless_reset_packet(QUICConnectionId connection_id, QUICStatelessToken stateless_reset_token) +{ + QUICPacket *packet = quicPacketAllocator.alloc(); + new (packet) QUICPacket(QUICPacketType::STATELESS_RESET, connection_id, stateless_reset_token); + return std::unique_ptr<QUICPacket, QUICPacketDeleterFunc>(packet, &QUICPacketDeleter::delete_packet); +} + void QUICPacketFactory::set_version(QUICVersion negotiated_version) { diff --git a/iocore/net/quic/QUICPacket.h b/iocore/net/quic/QUICPacket.h index 147f13d..e0e9c7a 100644 --- a/iocore/net/quic/QUICPacket.h +++ b/iocore/net/quic/QUICPacket.h @@ -56,6 +56,7 @@ public: 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); + static QUICPacketHeader *build(QUICPacketType, QUICConnectionId connection_id, QUICStatelessToken stateless_reset_token); virtual bool has_key_phase() const = 0; virtual bool has_connection_id() const = 0; virtual bool has_version() const = 0; @@ -135,6 +136,7 @@ public: 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(QUICPacketType type, QUICConnectionId connection_id, QUICStatelessToken stateless_reset_token); ~QUICPacket(); void set_protected_payload(ats_unique_buf cipher_txt, size_t cipher_txt_len); @@ -218,6 +220,8 @@ public: QUICPacketNumber base_packet_number, QUICVersion version, ats_unique_buf payload, size_t len); + std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> create_stateless_reset_packet(QUICConnectionId connection_id, + QUICStatelessToken stateless_reset_token); void set_version(QUICVersion negotiated_version); void set_crypto_module(QUICCrypto *crypto); diff --git a/iocore/net/quic/QUICTransportParameters.cc b/iocore/net/quic/QUICTransportParameters.cc index 2debfac..2ca7176 100644 --- a/iocore/net/quic/QUICTransportParameters.cc +++ b/iocore/net/quic/QUICTransportParameters.cc @@ -44,7 +44,7 @@ QUICTransportParameterValue::QUICTransportParameterValue(uint64_t raw_data, uint this->_len = len; }; -QUICTransportParameterValue::QUICTransportParameterValue(uint64_t raw_data[2], uint16_t l) +QUICTransportParameterValue::QUICTransportParameterValue(const uint64_t raw_data[2], uint16_t l) { this->_data = ats_unique_malloc(l); size_t len = 0; diff --git a/iocore/net/quic/QUICTransportParameters.h b/iocore/net/quic/QUICTransportParameters.h index 06adaf4..ba53a15 100644 --- a/iocore/net/quic/QUICTransportParameters.h +++ b/iocore/net/quic/QUICTransportParameters.h @@ -69,7 +69,7 @@ class QUICTransportParameterValue public: QUICTransportParameterValue(ats_unique_buf d, uint16_t l); QUICTransportParameterValue(uint64_t raw_data, uint16_t l); - QUICTransportParameterValue(uint64_t raw_data[2], uint16_t l); + QUICTransportParameterValue(const uint64_t raw_data[2], uint16_t l); const uint8_t *data() const; uint16_t len() const; diff --git a/iocore/net/quic/QUICTypes.h b/iocore/net/quic/QUICTypes.h index 2d0a095..2f3fc2f 100644 --- a/iocore/net/quic/QUICTypes.h +++ b/iocore/net/quic/QUICTypes.h @@ -72,7 +72,7 @@ enum class QUICPacketType : int { ZERO_RTT_PROTECTED, ONE_RTT_PROTECTED_KEY_PHASE_0, ONE_RTT_PROTECTED_KEY_PHASE_1, - PUBLIC_RESET, + STATELESS_RESET, UNINITIALIZED, }; @@ -173,10 +173,16 @@ public: ctx.finalize(_md5); } - const INK_MD5 - get() const + const uint8_t * + get_u8() const { - return _md5; + return _md5.u8; + } + + const uint64_t * + get_u64() const + { + return _md5.u64; } private: diff --git a/iocore/net/quic/test/test_QUICPacketFactory.cc b/iocore/net/quic/test/test_QUICPacketFactory.cc index ab989ae..88079db 100644 --- a/iocore/net/quic/test/test_QUICPacketFactory.cc +++ b/iocore/net/quic/test/test_QUICPacketFactory.cc @@ -68,3 +68,31 @@ TEST_CASE("QUICPacketFactory_Create_ServerCleartextPacket", "[quic]") CHECK((packet->packet_number() & 0xFFFFFFFF80000000) == 0); CHECK(packet->version() == 0x11223344); } + +TEST_CASE("QUICPacketFactory_Create_StatelessResetPacket", "[quic]") +{ + QUICPacketFactory factory; + QUICStatelessToken token; + token.gen_token("test", 12345); + uint8_t expected_output[] = { + 0x41, // 0CK0001 + 0x00, 0x00, 0x00, 0x00, 0x01, + 0x02, 0x03, 0x04, // Connection ID + 0x40, 0x01, 0x57, 0x55, 0x21, + 0x9c, 0x24, 0x24, // Token + 0xc7, 0x9f, 0x79, 0xa2, 0x72, + 0xcb, 0x55, 0xe6 + // Random data + }; + uint8_t output[1024]; + size_t out_len = 0; + + std::unique_ptr<QUICPacket, QUICPacketDeleterFunc> packet = factory.create_stateless_reset_packet(0x01020304, token); + CHECK(packet->type() == QUICPacketType::STATELESS_RESET); + CHECK(packet->connection_id() == 0x01020304); + CHECK(packet->packet_number() == token.get_u8()[0]); + CHECK(memcmp(packet->payload(), token.get_u8() + 1, 15) == 0); + packet->store(output, &out_len); + CHECK(memcmp(output, expected_output, 25) == 0); + CHECK(out_len > 25); // Check existence of random bytes at the end +} -- To stop receiving notification emails like this one, please contact ['"commits@trafficserver.apache.org" <commits@trafficserver.apache.org>'].