From b3d0856f92db4845819815039e47563f2bee7bc5 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 12 Aug 2020 12:35:08 -0700 Subject: [PATCH] quic: fixups after ngtcp2/nghttp3 update Signed-off-by: James M Snell --- src/quic/node_quic_crypto.cc | 22 ++++++++++++++++++++-- src/quic/node_quic_session-inl.h | 2 ++ src/quic/node_quic_session.cc | 28 ++++++++++++++++++---------- src/quic/node_quic_session.h | 11 +++++++---- 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/quic/node_quic_crypto.cc b/src/quic/node_quic_crypto.cc index b073ca9c381487..11a7deccb4f003 100644 --- a/src/quic/node_quic_crypto.cc +++ b/src/quic/node_quic_crypto.cc @@ -164,13 +164,22 @@ bool GenerateRetryToken( return false; } + ngtcp2_crypto_aead_ctx aead_ctx; + if (NGTCP2_ERR(ngtcp2_crypto_aead_ctx_encrypt_init( + &aead_ctx, + &ctx.aead, + token_key, + ivlen))) { + return false; + } + size_t plaintextlen = std::distance(std::begin(plaintext), p); if (NGTCP2_ERR(ngtcp2_crypto_encrypt( token, &ctx.aead, + &aead_ctx, plaintext.data(), plaintextlen, - token_key, token_iv, ivlen, addr.raw(), @@ -291,12 +300,21 @@ bool InvalidRetryToken( uint8_t plaintext[4096]; + ngtcp2_crypto_aead_ctx aead_ctx; + if (NGTCP2_ERR(ngtcp2_crypto_aead_ctx_decrypt_init( + &aead_ctx, + &ctx.aead, + token_key, + ivlen))) { + return true; + } + if (NGTCP2_ERR(ngtcp2_crypto_decrypt( plaintext, &ctx.aead, + &aead_ctx, ciphertext, ciphertextlen, - token_key, token_iv, ivlen, addr.raw(), diff --git a/src/quic/node_quic_session-inl.h b/src/quic/node_quic_session-inl.h index 8b1ac00806c4db..29cf689be7b8ef 100644 --- a/src/quic/node_quic_session-inl.h +++ b/src/quic/node_quic_session-inl.h @@ -50,6 +50,8 @@ void QuicSessionConfig::set_original_connection_id( transport_params.original_dcid = *ocid; transport_params.retry_scid = *scid; transport_params.retry_scid_present = 1; + } else { + transport_params.original_dcid = *scid; } } diff --git a/src/quic/node_quic_session.cc b/src/quic/node_quic_session.cc index 59f80c77057598..ba8bd0fb187f15 100644 --- a/src/quic/node_quic_session.cc +++ b/src/quic/node_quic_session.cc @@ -1422,7 +1422,7 @@ bool QuicApplication::SendPendingData() { continue; case NGTCP2_ERR_STREAM_NOT_FOUND: continue; - case NGTCP2_ERR_WRITE_STREAM_MORE: + case NGTCP2_ERR_WRITE_MORE: CHECK_GT(ndatalen, 0); CHECK(StreamCommit(&stream_data, ndatalen)); pos += ndatalen; @@ -2096,7 +2096,6 @@ bool QuicSession::Receive( if (!is_destroyed()) UpdateIdleTimer(); - SendPendingData(); Debug(this, "Successfully processed received packet"); return true; @@ -2239,8 +2238,11 @@ void QuicSession::RemoveStream(int64_t stream_id) { void QuicSession::ScheduleRetransmit() { uint64_t now = uv_hrtime(); uint64_t expiry = ngtcp2_conn_get_expiry(connection()); - uint64_t interval = (expiry - now) / 1000000UL; - if (expiry < now || interval == 0) interval = 1; + // now and expiry are in nanoseconds, interval is milliseconds + uint64_t interval = (expiry < now) ? 1 : (expiry - now) / 1000000UL; + // If interval ends up being 0, the repeating timer won't be + // scheduled, so set it to 1 instead. + if (interval == 0) interval = 1; Debug(this, "Scheduling the retransmit timer for %" PRIu64, interval); UpdateRetransmitTimer(interval); } @@ -2440,7 +2442,7 @@ bool QuicSession::SendPacket(std::unique_ptr packet) { IncrementStat(&QuicSessionStats::bytes_sent, packet->length()); RecordTimestamp(&QuicSessionStats::sent_at); - ScheduleRetransmit(); +// ScheduleRetransmit(); Debug(this, "Sending %" PRIu64 " bytes to %s from %s", packet->length(), @@ -2471,6 +2473,7 @@ void QuicSession::SendPendingData() { Debug(this, "Error sending QUIC application data"); HandleError(); } + ScheduleRetransmit(); } // When completing the TLS handshake, the TLS session information @@ -3392,11 +3395,9 @@ int QuicSession::OnStreamReset( // Currently, there is only one use. In the future, we'll want to // explore whether we want to handle the different cases uses. int QuicSession::OnRand( - ngtcp2_conn* conn, uint8_t* dest, size_t destlen, - ngtcp2_rand_ctx ctx, - void* user_data) { + ngtcp2_rand_ctx ctx) { EntropySource(dest, destlen); return 0; } @@ -3541,6 +3542,8 @@ const ngtcp2_conn_callbacks QuicSession::callbacks[2] = { OnConnectionIDStatus, OnHandshakeConfirmed, nullptr, // recv_new_token + ngtcp2_crypto_delete_crypto_aead_ctx_cb, + ngtcp2_crypto_delete_crypto_cipher_ctx_cb, }, // NGTCP2_CRYPTO_SIDE_SERVER { @@ -3574,6 +3577,8 @@ const ngtcp2_conn_callbacks QuicSession::callbacks[2] = { OnConnectionIDStatus, nullptr, // handshake_confirmed nullptr, // recv_new_token + ngtcp2_crypto_delete_crypto_aead_ctx_cb, + ngtcp2_crypto_delete_crypto_cipher_ctx_cb, } }; @@ -3585,7 +3590,11 @@ BaseObjectPtr QuicSession::qlog_stream() { return qlog_stream_; } -void QuicSession::OnQlogWrite(void* user_data, const void* data, size_t len) { +void QuicSession::OnQlogWrite( + void* user_data, + uint32_t flags, + const void* data, + size_t len) { QuicSession* session = static_cast(user_data); Environment* env = session->env(); @@ -3888,7 +3897,6 @@ void NewQuicClientSession(const FunctionCallbackInfo& args) { args[ARG_IDX::QLOG]->IsTrue() ? QlogMode::kEnabled : QlogMode::kDisabled); - session->SendPendingData(); if (session->is_destroyed()) return args.GetReturnValue().Set(ERR_FAILED_TO_CREATE_SESSION); diff --git a/src/quic/node_quic_session.h b/src/quic/node_quic_session.h index 4bd14310e15181..fc09eab84584f4 100644 --- a/src/quic/node_quic_session.h +++ b/src/quic/node_quic_session.h @@ -75,6 +75,7 @@ class QuicSessionConfig final : public ngtcp2_settings { QuicSessionConfig(const QuicSessionConfig& config) { initial_ts = uv_hrtime(); + initial_rtt = config.initial_rtt; transport_params = config.transport_params; max_udp_payload_size = config.max_udp_payload_size; cc_algo = config.cc_algo; @@ -1366,11 +1367,9 @@ class QuicSession final : public AsyncWrap, void* stream_user_data); static int OnRand( - ngtcp2_conn* conn, uint8_t* dest, size_t destlen, - ngtcp2_rand_ctx ctx, - void* user_data); + ngtcp2_rand_ctx ctx); static int OnGetNewConnectionID( ngtcp2_conn* conn, @@ -1437,7 +1436,11 @@ class QuicSession final : public AsyncWrap, const uint8_t* token, void* user_data); - static void OnQlogWrite(void* user_data, const void* data, size_t len); + static void OnQlogWrite( + void* user_data, + uint32_t flags, + const void* data, + size_t len); #define V(id, _) QUICSESSION_FLAG_##id, enum QuicSessionFlags : uint32_t {