Skip to content

Commit d603418

Browse files
committed
quic: cleanups for QuicSocket
PR-URL: #34137 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: David Carlier <[email protected]>
1 parent 73a51bb commit d603418

File tree

5 files changed

+96
-67
lines changed

5 files changed

+96
-67
lines changed

Diff for: src/env.h

-1
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,6 @@ constexpr size_t kFsStatsBufferLength =
450450
#if defined(NODE_EXPERIMENTAL_QUIC) && NODE_EXPERIMENTAL_QUIC
451451
# define QUIC_ENVIRONMENT_STRONG_PERSISTENT_VALUES(V) \
452452
V(quic_on_socket_close_function, v8::Function) \
453-
V(quic_on_socket_error_function, v8::Function) \
454453
V(quic_on_socket_server_busy_function, v8::Function) \
455454
V(quic_on_session_cert_function, v8::Function) \
456455
V(quic_on_session_client_hello_function, v8::Function) \

Diff for: src/quic/node_quic_session.cc

+1-1
Original file line numberDiff line numberDiff line change
@@ -2323,7 +2323,7 @@ bool QuicSession::set_socket(QuicSocket* socket, bool nat_rebinding) {
23232323
socket->ReceiveStart();
23242324

23252325
// Step 4: Update ngtcp2
2326-
auto& local_address = socket->local_address();
2326+
auto local_address = socket->local_address();
23272327
if (nat_rebinding) {
23282328
ngtcp2_addr addr;
23292329
ngtcp2_addr_init(

Diff for: src/quic/node_quic_socket-inl.h

+2-6
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,8 @@ void QuicSocket::AssociateStatelessResetToken(
7979
token_map_[token] = session;
8080
}
8181

82-
const SocketAddress& QuicSocket::local_address() {
83-
CHECK(preferred_endpoint_);
82+
SocketAddress QuicSocket::local_address() const {
83+
DCHECK(preferred_endpoint_);
8484
return preferred_endpoint_->local_address();
8585
}
8686

@@ -221,10 +221,6 @@ void QuicSocket::AddEndpoint(
221221
endpoint_->ReceiveStart();
222222
}
223223

224-
void QuicSocket::SessionReady(BaseObjectPtr<QuicSession> session) {
225-
listener_->OnSessionReady(session);
226-
}
227-
228224
} // namespace quic
229225
} // namespace node
230226

Diff for: src/quic/node_quic_socket.cc

+64-37
Original file line numberDiff line numberDiff line change
@@ -83,10 +83,10 @@ bool IsShortHeader(
8383
}
8484
} // namespace
8585

86-
QuicPacket::QuicPacket(const char* diagnostic_label, size_t len) :
87-
data_{0},
88-
len_(len),
89-
diagnostic_label_(diagnostic_label) {
86+
QuicPacket::QuicPacket(const char* diagnostic_label, size_t len)
87+
: data_{0},
88+
len_(len),
89+
diagnostic_label_(diagnostic_label) {
9090
CHECK_LE(len, MAX_PKTLEN);
9191
}
9292

@@ -100,8 +100,6 @@ const char* QuicPacket::diagnostic_label() const {
100100
diagnostic_label_ : "unspecified";
101101
}
102102

103-
void QuicPacket::MemoryInfo(MemoryTracker* tracker) const {}
104-
105103
QuicSocketListener::~QuicSocketListener() {
106104
if (socket_)
107105
socket_->RemoveListener(this);
@@ -174,10 +172,10 @@ QuicEndpoint::QuicEndpoint(
174172
QuicState* quic_state,
175173
Local<Object> wrap,
176174
QuicSocket* listener,
177-
Local<Object> udp_wrap) :
178-
BaseObject(quic_state->env(), wrap),
179-
listener_(listener),
180-
quic_state_(quic_state) {
175+
Local<Object> udp_wrap)
176+
: BaseObject(quic_state->env(), wrap),
177+
listener_(listener),
178+
quic_state_(quic_state) {
181179
MakeWeak();
182180
udp_ = static_cast<UDPWrapBase*>(
183181
udp_wrap->GetAlignedPointerFromInternalField(
@@ -187,7 +185,9 @@ QuicEndpoint::QuicEndpoint(
187185
strong_ptr_.reset(udp_->GetAsyncWrap());
188186
}
189187

190-
void QuicEndpoint::MemoryInfo(MemoryTracker* tracker) const {}
188+
QuicEndpoint::~QuicEndpoint() {
189+
udp_->set_listener(nullptr);
190+
}
191191

192192
uv_buf_t QuicEndpoint::OnAlloc(size_t suggested_size) {
193193
return AllocatedBuffer::AllocateManaged(env(), suggested_size).release();
@@ -229,6 +229,14 @@ void QuicEndpoint::OnAfterBind() {
229229
listener_->OnBind(this);
230230
}
231231

232+
template <typename Fn>
233+
void QuicSocketStatsTraits::ToString(const QuicSocket& ptr, Fn&& add_field) {
234+
#define V(_n, name, label) \
235+
add_field(label, ptr.GetStat(&QuicSocketStats::name));
236+
SOCKET_STATS(V)
237+
#undef V
238+
}
239+
232240
QuicSocket::QuicSocket(
233241
QuicState* quic_state,
234242
Local<Object> wrap,
@@ -240,17 +248,17 @@ QuicSocket::QuicSocket(
240248
QlogMode qlog,
241249
const uint8_t* session_reset_secret,
242250
bool disable_stateless_reset)
243-
: AsyncWrap(quic_state->env(), wrap, AsyncWrap::PROVIDER_QUICSOCKET),
244-
StatsBase(quic_state->env(), wrap),
245-
alloc_info_(MakeAllocator()),
246-
options_(options),
247-
max_connections_(max_connections),
248-
max_connections_per_host_(max_connections_per_host),
249-
max_stateless_resets_per_host_(max_stateless_resets_per_host),
250-
retry_token_expiration_(retry_token_expiration),
251-
qlog_(qlog),
252-
server_alpn_(NGHTTP3_ALPN_H3),
253-
quic_state_(quic_state) {
251+
: AsyncWrap(quic_state->env(), wrap, AsyncWrap::PROVIDER_QUICSOCKET),
252+
StatsBase(quic_state->env(), wrap),
253+
alloc_info_(MakeAllocator()),
254+
options_(options),
255+
max_connections_(max_connections),
256+
max_connections_per_host_(max_connections_per_host),
257+
max_stateless_resets_per_host_(max_stateless_resets_per_host),
258+
retry_token_expiration_(retry_token_expiration),
259+
qlog_(qlog),
260+
server_alpn_(NGHTTP3_ALPN_H3),
261+
quic_state_(quic_state) {
254262
MakeWeak();
255263
PushListener(&default_listener_);
256264

@@ -279,15 +287,13 @@ QuicSocket::~QuicSocket() {
279287
if (listener == listener_)
280288
RemoveListener(listener_);
281289

282-
DebugStats();
283-
}
290+
// In a clean shutdown, all QuicSessions associated with the QuicSocket
291+
// would have been destroyed explicitly. However, if the QuicSocket is
292+
// garbage collected / freed before Destroy having been called, there
293+
// may be sessions remaining. This is not really a good thing.
294+
Debug(this, "Destroying with %d sessions remaining", sessions_.size());
284295

285-
template <typename Fn>
286-
void QuicSocketStatsTraits::ToString(const QuicSocket& ptr, Fn&& add_field) {
287-
#define V(_n, name, label) \
288-
add_field(label, ptr.GetStat(&QuicSocketStats::name));
289-
SOCKET_STATS(V)
290-
#undef V
296+
DebugStats();
291297
}
292298

293299
void QuicSocket::MemoryInfo(MemoryTracker* tracker) const {
@@ -310,7 +316,6 @@ void QuicSocket::Listen(
310316
const std::string& alpn,
311317
uint32_t options) {
312318
CHECK(sc);
313-
CHECK(!server_secure_context_);
314319
CHECK(!is_flag_set(QUICSOCKET_FLAGS_SERVER_LISTENING));
315320
Debug(this, "Starting to listen");
316321
server_session_config_.Set(quic_state(), preferred_address);
@@ -323,6 +328,7 @@ void QuicSocket::Listen(
323328
}
324329

325330
void QuicSocket::OnError(QuicEndpoint* endpoint, ssize_t error) {
331+
// TODO(@jasnell): What should we do with the endpoint?
326332
Debug(this, "Reading data from UDP socket failed. Error %" PRId64, error);
327333
listener_->OnError(error);
328334
}
@@ -341,7 +347,7 @@ void QuicSocket::OnEndpointDone(QuicEndpoint* endpoint) {
341347
}
342348

343349
void QuicSocket::OnBind(QuicEndpoint* endpoint) {
344-
const SocketAddress& local_address = endpoint->local_address();
350+
SocketAddress local_address = endpoint->local_address();
345351
bound_endpoints_[local_address] =
346352
BaseObjectWeakPtr<QuicEndpoint>(endpoint);
347353
Debug(this, "Endpoint %s bound", local_address);
@@ -545,6 +551,13 @@ void QuicSocket::OnReceive(
545551
IncrementStat(&QuicSocketStats::packets_ignored);
546552
return;
547553
}
554+
555+
// The QuicSession was destroyed while it was being set up. There's
556+
// no further processing we can do here.
557+
if (session->is_destroyed()) {
558+
IncrementStat(&QuicSocketStats::packets_ignored);
559+
return;
560+
}
548561
}
549562

550563
CHECK(session);
@@ -683,6 +696,8 @@ bool QuicSocket::SendRetry(
683696
}
684697

685698
// Shutdown a connection prematurely, before a QuicSession is created.
699+
// This should only be called t the start of a session before the crypto
700+
// keys have been established.
686701
void QuicSocket::ImmediateConnectionClose(
687702
const QuicCID& scid,
688703
const QuicCID& dcid,
@@ -819,16 +834,28 @@ BaseObjectPtr<QuicSession> QuicSocket::AcceptInitialPacket(
819834

820835
listener_->OnSessionReady(session);
821836

837+
// It's possible that the session was destroyed while processing
838+
// the ready callback. If it was, then we need to send an early
839+
// CONNECTION_CLOSE.
840+
if (session->is_destroyed()) {
841+
ImmediateConnectionClose(
842+
QuicCID(hd.scid),
843+
QuicCID(hd.dcid),
844+
local_addr,
845+
remote_addr,
846+
NGTCP2_CONNECTION_REFUSED);
847+
}
848+
822849
return session;
823850
}
824851

825852
QuicSocket::SendWrap::SendWrap(
826853
QuicState* quic_state,
827854
Local<Object> req_wrap_obj,
828855
size_t total_length)
829-
: ReqWrap(quic_state->env(), req_wrap_obj, PROVIDER_QUICSOCKET),
830-
total_length_(total_length),
831-
quic_state_(quic_state) {
856+
: ReqWrap(quic_state->env(), req_wrap_obj, PROVIDER_QUICSOCKET),
857+
total_length_(total_length),
858+
quic_state_(quic_state) {
832859
}
833860

834861
std::string QuicSocket::SendWrap::MemoryInfoName() const {
@@ -1093,7 +1120,7 @@ void QuicSocketStopListening(const FunctionCallbackInfo<Value>& args) {
10931120
socket->StopListening();
10941121
}
10951122

1096-
void QuicSocketset_server_busy(const FunctionCallbackInfo<Value>& args) {
1123+
void QuicSocketSetServerBusy(const FunctionCallbackInfo<Value>& args) {
10971124
QuicSocket* socket;
10981125
ASSIGN_OR_RETURN_UNWRAP(&socket, args.Holder());
10991126
CHECK_EQ(args.Length(), 1);
@@ -1164,7 +1191,7 @@ void QuicSocket::Initialize(
11641191
QuicSocketSetDiagnosticPacketLoss);
11651192
env->SetProtoMethod(socket,
11661193
"setServerBusy",
1167-
QuicSocketset_server_busy);
1194+
QuicSocketSetServerBusy);
11681195
env->SetProtoMethod(socket,
11691196
"stopListening",
11701197
QuicSocketStopListening);

0 commit comments

Comments
 (0)