Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

quic: resolving more outstanding TODO comments #34865

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions deps/nghttp3/lib/nghttp3_ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,25 @@

#include "nghttp3_macro.h"

#if defined(_MSC_VER) && defined(_M_ARM64)
unsigned int __popcnt(unsigned int x) {
#if defined(_WIN32)
# if defined(_M_ARM64)
unsigned int __nghttp3_popcnt(unsigned int x) {
lundibundi marked this conversation as resolved.
Show resolved Hide resolved
unsigned int c = 0;
for (; x; ++c) {
x &= x - 1;
}
return c;
}
# else
# define __nghttp3_popcnt __popcnt
# endif
#endif

int nghttp3_ringbuf_init(nghttp3_ringbuf *rb, size_t nmemb, size_t size,
const nghttp3_mem *mem) {
if (nmemb) {
#ifdef WIN32
assert(1 == __popcnt((unsigned int)nmemb));
assert(1 == __nghttp3_popcnt((unsigned int)nmemb));
#else
assert(1 == __builtin_popcount((unsigned int)nmemb));
#endif
Expand Down Expand Up @@ -127,7 +131,7 @@ int nghttp3_ringbuf_reserve(nghttp3_ringbuf *rb, size_t nmemb) {
}

#ifdef WIN32
assert(1 == __popcnt((unsigned int)nmemb));
assert(1 == __nghttp3_popcnt((unsigned int)nmemb));
#else
assert(1 == __builtin_popcount((unsigned int)nmemb));
#endif
Expand Down
10 changes: 7 additions & 3 deletions deps/ngtcp2/lib/ngtcp2_ringbuf.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,20 +31,24 @@

#include "ngtcp2_macro.h"

#if defined(_MSC_VER) && defined(_M_ARM64)
unsigned int __popcnt(unsigned int x) {
#if defined(_WIN32)
# if defined(_M_ARM64)
unsigned int __ngtcp2_popcnt(unsigned int x) {
unsigned int c = 0;
for (; x; ++c) {
x &= x - 1;
}
return c;
}
# else
# define __ngtcp2_popcnt __popcnt
# endif
#endif

int ngtcp2_ringbuf_init(ngtcp2_ringbuf *rb, size_t nmemb, size_t size,
const ngtcp2_mem *mem) {
#ifdef WIN32
assert(1 == __popcnt((unsigned int)nmemb));
assert(1 == __ngtcp2_popcnt((unsigned int)nmemb));
#else
assert(1 == __builtin_popcount((unsigned int)nmemb));
#endif
Expand Down
15 changes: 6 additions & 9 deletions src/quic/node_quic_http3_application.cc
Original file line number Diff line number Diff line change
Expand Up @@ -646,7 +646,7 @@ void Http3Application::BeginHeaders(
// by the QuicStream until stream->EndHeaders() is called, during which
// the collected headers are converted to an array and passed off to
// the javascript side.
bool Http3Application::ReceiveHeader(
void Http3Application::ReceiveHeader(
int64_t stream_id,
int32_t token,
nghttp3_rcbuf* name,
Expand All @@ -671,9 +671,9 @@ bool Http3Application::ReceiveHeader(
name,
value,
flags);
return stream->AddHeader(std::move(header));
// At this level, we don't care if the header is added or not.
USE(stream->AddHeader(std::move(header)));
}
return true;
}

// Marks the completion of a headers block.
Expand Down Expand Up @@ -830,10 +830,8 @@ int Http3Application::OnReceiveHeader(
void* conn_user_data,
void* stream_user_data) {
Http3Application* app = static_cast<Http3Application*>(conn_user_data);
// TODO(@jasnell): Need to determine the appropriate response code here
// for when the header is not going to be accepted.
return app->ReceiveHeader(stream_id, token, name, value, flags) ?
0 : NGHTTP3_ERR_CALLBACK_FAILURE;
app->ReceiveHeader(stream_id, token, name, value, flags);
return 0;
}

int Http3Application::OnEndHeaders(
Expand Down Expand Up @@ -868,8 +866,7 @@ int Http3Application::OnReceivePushPromise(
void* conn_user_data,
void* stream_user_data) {
Http3Application* app = static_cast<Http3Application*>(conn_user_data);
if (!app->ReceiveHeader(stream_id, token, name, value, flags))
return NGHTTP3_ERR_CALLBACK_FAILURE;
app->ReceiveHeader(stream_id, token, name, value, flags);
return 0;
}

Expand Down
2 changes: 1 addition & 1 deletion src/quic/node_quic_http3_application.h
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ class Http3Application final :
void BeginHeaders(
int64_t stream_id,
QuicStreamHeadersKind kind = QUICSTREAM_HEADERS_KIND_NONE);
bool ReceiveHeader(
void ReceiveHeader(
int64_t stream_id,
int32_t token,
nghttp3_rcbuf* name,
Expand Down
10 changes: 2 additions & 8 deletions src/quic/node_quic_session.cc
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,8 @@ std::string QuicSession::RemoteTransportParamsDebug::ToString() const {
out += " Original Connection ID: N/A \n";
}

if (params.preferred_address_present) {
out += " Preferred Address Present: Yes\n";
// TODO(@jasnell): Serialize the IPv4 and IPv6 address options
} else {
out += " Preferred Address Present: No\n";
}
out += " Preferred Address Present: " +
params.preferred_address_present ? "Yes" : "No";

if (params.stateless_reset_token_present) {
StatelessResetToken token(params.stateless_reset_token);
Expand Down Expand Up @@ -3617,8 +3613,6 @@ void QuicSession::OnQlogWrite(
BaseObjectPtr<QLogStream> QLogStream::Create(Environment* env) {
HandleScope scope(env->isolate());

// TODO(@jasnell): There is identical code in heap_utils for the
// HeapSnapshotStream. We can consolidate the two.
if (env->qlogoutputstream_constructor_template().IsEmpty()) {
// Create FunctionTemplate for QLogStream
Local<FunctionTemplate> os = FunctionTemplate::New(env->isolate());
Expand Down
20 changes: 9 additions & 11 deletions src/quic/node_quic_socket.cc
Original file line number Diff line number Diff line change
Expand Up @@ -542,19 +542,17 @@ void QuicSocket::OnReceive(
// a stateless reset. The stateless reset contains a token derived
// from the received destination connection ID.
//
// TODO(@jasnell): Stateless resets are generated programmatically
// using HKDF with the sender provided dcid and a locally provided
// secret as input. It is entirely possible that a malicious
// peer could send multiple stateless reset eliciting packets
// with the specific intent of using the returned stateless
// reset to guess the stateless reset token secret used by
// the server. Once guessed, the malicious peer could use
// Stateless resets are generated programmatically using HKDF with
// the sender provided dcid and a locally provided secret as input.
// It is entirely possible that a malicious peer could send multiple
// stateless reset eliciting packets with the specific intent of using
// the returned stateless reset to guess the stateless reset token
// secret used by the server. Once guessed, the malicious peer could use
// that secret as a DOS vector against other peers. We currently
// implement some mitigations for this by limiting the number
// of stateless resets that can be sent to a specific remote
// address but there are other possible mitigations, such as
// including the remote address as input in the generation of
// the stateless token.
// address and we generate a random nonce used in creation of the
// token.
if (is_short_header &&
SendStatelessReset(dcid, local_addr, remote_addr, nread)) {
Debug(this, "Sent stateless reset");
Expand Down Expand Up @@ -620,7 +618,7 @@ void QuicSocket::SendVersionNegotiation(
SendPacket(local_addr, remote_address, std::move(packet));
}

// Possible generates and sends a stateless reset packet.
// Possibly generates and sends a stateless reset packet.
// This is terminal for the connection. It is possible
// that a malicious packet triggered this so we need to
// be careful not to commit too many resources.
Expand Down