@@ -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-
105103QuicSocketListener::~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
192192uv_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+
232240QuicSocket::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
293299void 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
325330void 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
343349void 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.
686701void 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
825852QuicSocket::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
834861std::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