Skip to content

Commit a3fa3f2

Browse files
addaleaxjuanarbol
authored andcommitted
quic: support memory tracking
Fixes: nodejs#59 PR-URL: nodejs#145 Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 7bace89 commit a3fa3f2

7 files changed

Lines changed: 69 additions & 29 deletions

File tree

src/node_quic_session.cc

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,24 @@ bool QuicSession::UpdateKey() {
18831883
&crypto_ctx_);
18841884
}
18851885

1886+
void QuicSession::MemoryInfo(MemoryTracker* tracker) const {
1887+
tracker->TrackField("alpn", alpn_);
1888+
tracker->TrackField("idle", idle_);
1889+
tracker->TrackField("retransmit", retransmit_);
1890+
tracker->TrackField("rx_secret", rx_secret_);
1891+
tracker->TrackField("tx_secret", tx_secret_);
1892+
tracker->TrackField("sendbuf", sendbuf_);
1893+
tracker->TrackField("handshake", handshake_);
1894+
tracker->TrackField("txbuf", txbuf_);
1895+
tracker->TrackField("peer_handshake", peer_handshake_);
1896+
tracker->TrackField("streams", streams_);
1897+
tracker->TrackField("state", state_);
1898+
tracker->TrackField("crypto_rx_ack", crypto_rx_ack_);
1899+
tracker->TrackField("crypto_handshake_rate", crypto_handshake_rate_);
1900+
tracker->TrackField("stats_buffer", stats_buffer_);
1901+
tracker->TrackField("recovery_stats_buffer", recovery_stats_buffer_);
1902+
tracker->TrackFieldWithSize("current_ngtcp2_memory", current_ngtcp2_memory_);
1903+
}
18861904

18871905
// QuicServerSession
18881906
QuicServerSession::InitialPacketResult QuicServerSession::Accept(
@@ -2376,6 +2394,11 @@ int QuicServerSession::VerifyPeerIdentity(const char* hostname) {
23762394
return VerifyPeerCertificate(ssl());
23772395
}
23782396

2397+
void QuicServerSession::MemoryInfo(MemoryTracker* tracker) const {
2398+
QuicSession::MemoryInfo(tracker);
2399+
tracker->TrackField("conn_closebuf", conn_closebuf_);
2400+
tracker->TrackField("ocsp_response", ocsp_response_);
2401+
}
23792402

23802403
// QuicClientSession
23812404

@@ -2888,6 +2911,11 @@ int QuicClientSession::VerifyPeerIdentity(const char* hostname) {
28882911
return 0;
28892912
}
28902913

2914+
void QuicClientSession::MemoryInfo(MemoryTracker* tracker) const {
2915+
QuicSession::MemoryInfo(tracker);
2916+
tracker->TrackField("hostname", hostname_);
2917+
}
2918+
28912919
// Static ngtcp2 callbacks are registered when ngtcp2 when a new ngtcp2_conn is
28922920
// created. These are static functions that, for the most part, simply defer to
28932921
// a QuicSession instance that is passed through as user_data.

src/node_quic_session.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,6 +364,8 @@ class QuicSession : public AsyncWrap,
364364
QuicSession* session_;
365365
};
366366

367+
void MemoryInfo(MemoryTracker* tracker) const override;
368+
367369
private:
368370
// Returns true if the QuicSession has entered the
369371
// closing period following a call to ImmediateClose.
@@ -1063,7 +1065,8 @@ class QuicServerSession : public QuicSession {
10631065
const ngtcp2_cid* rcid() const { return &rcid_; }
10641066
ngtcp2_cid* pscid() { return &pscid_; }
10651067

1066-
void MemoryInfo(MemoryTracker* tracker) const override {}
1068+
void MemoryInfo(MemoryTracker* tracker) const override;
1069+
10671070
SET_MEMORY_INFO_NAME(QuicServerSession)
10681071
SET_SELF_SIZE(QuicServerSession)
10691072

@@ -1168,7 +1171,8 @@ class QuicClientSession : public QuicSession {
11681171

11691172
bool SendConnectionClose() override;
11701173

1171-
void MemoryInfo(MemoryTracker* tracker) const override {}
1174+
void MemoryInfo(MemoryTracker* tracker) const override;
1175+
11721176
SET_MEMORY_INFO_NAME(QuicClientSession)
11731177
SET_SELF_SIZE(QuicClientSession)
11741178

src/node_quic_socket.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,13 @@ QuicSocket::~QuicSocket() {
120120
}
121121

122122
void QuicSocket::MemoryInfo(MemoryTracker* tracker) const {
123-
// TODO(@jasnell): Implement memory tracking information
123+
tracker->TrackField("sessions", sessions_);
124+
tracker->TrackField("dcid_to_scid", dcid_to_scid_);
125+
tracker->TrackFieldWithSize("addr_counts",
126+
addr_counts_.size() * (sizeof(sockaddr*) + sizeof(size_t)));
127+
tracker->TrackField("validated_addrs", validated_addrs_);
128+
tracker->TrackField("stats_buffer", stats_buffer_);
129+
tracker->TrackFieldWithSize("current_ngtcp2_memory", current_ngtcp2_memory_);
124130
}
125131

126132
void QuicSocket::AddSession(

src/node_quic_stream.cc

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,14 @@ BaseObjectPtr<QuicStream> QuicStream::New(
379379
return stream;
380380
}
381381

382+
void QuicStream::MemoryInfo(MemoryTracker* tracker) const {
383+
tracker->TrackField("buffer", &streambuf_);
384+
tracker->TrackField("data_rx_rate", data_rx_rate_);
385+
tracker->TrackField("data_rx_size", data_rx_size_);
386+
tracker->TrackField("data_rx_ack", data_rx_ack_);
387+
tracker->TrackField("stats_buffer", stats_buffer_);
388+
}
389+
382390
// JavaScript API
383391
namespace {
384392
void QuicStreamGetID(const FunctionCallbackInfo<Value>& args) {

src/node_quic_stream.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,9 +296,7 @@ class QuicStream : public AsyncWrap, public StreamBase {
296296

297297
AsyncWrap* GetAsyncWrap() override { return this; }
298298

299-
void MemoryInfo(MemoryTracker* tracker) const override {
300-
tracker->TrackField("buffer", &streambuf_);
301-
}
299+
void MemoryInfo(MemoryTracker* tracker) const override;
302300

303301
SET_MEMORY_INFO_NAME(QuicStream)
304302
SET_SELF_SIZE(QuicStream)

src/node_quic_util.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ void IncrementStat(
384384
// Simple timer wrapper that is used to implement the internals
385385
// for idle and retransmission timeouts. Call Update to start or
386386
// reset the timer; Stop to halt the timer.
387-
class Timer {
387+
class Timer final : public MemoryRetainer {
388388
public:
389389
explicit Timer(Environment* env, std::function<void()> fn)
390390
: stopped_(false),
@@ -395,7 +395,7 @@ class Timer {
395395
env->AddCleanupHook(CleanupHook, this);
396396
}
397397

398-
~Timer() {
398+
~Timer() override {
399399
env_->RemoveCleanupHook(CleanupHook, this);
400400
}
401401

@@ -423,6 +423,10 @@ class Timer {
423423

424424
static void Free(Timer* timer);
425425

426+
SET_NO_MEMORY_INFO()
427+
SET_MEMORY_INFO_NAME(Timer)
428+
SET_SELF_SIZE(Timer)
429+
426430
private:
427431
static void OnTimeout(uv_timer_t* timer);
428432
static void CleanupHook(void* data);

test/pummel/test-heapdump-quic.js

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,66 +69,58 @@ server.on('session', common.mustCall((session) => {
6969
}
7070
], { loose: true });
7171

72-
state.validateSnapshotNodes('Node / QuicSession', [
72+
state.validateSnapshotNodes('Node / QuicServerSession', [
7373
{
7474
children: [
7575
{ node_name: 'QuicServerSession', edge_name: 'wrapped' },
76-
{ node_name: 'Node / QuicCryptoContext',
77-
edge_name: 'crypto_context' },
76+
{ node_name: 'Node / rx_secret', edge_name: 'rx_secret' },
77+
{ node_name: 'Node / tx_secret', edge_name: 'tx_secret' },
7878
{ node_name: 'Node / HistogramBase', edge_name: 'crypto_rx_ack' },
7979
{ node_name: 'Node / HistogramBase',
8080
edge_name: 'crypto_handshake_rate' },
8181
{ node_name: 'Node / Timer', edge_name: 'retransmit' },
8282
{ node_name: 'Node / Timer', edge_name: 'idle' },
8383
{ node_name: 'Node / QuicBuffer', edge_name: 'sendbuf' },
8484
{ node_name: 'Node / QuicBuffer', edge_name: 'txbuf' },
85+
{ node_name: 'Node / peer_handshake', edge_name: 'peer_handshake' },
8586
{ node_name: 'Float64Array', edge_name: 'recovery_stats_buffer' },
8687
{ node_name: 'BigUint64Array', edge_name: 'stats_buffer' },
8788
{ node_name: 'Node / current_ngtcp2_memory',
8889
edge_name: 'current_ngtcp2_memory' },
8990
{ node_name: 'Node / streams', edge_name: 'streams' },
91+
{ node_name: 'Node / QuicBuffer', edge_name: 'handshake' },
9092
{ node_name: 'Node / std::basic_string', edge_name: 'alpn' },
91-
{ node_name: 'Node / std::basic_string', edge_name: 'hostname' },
9293
{ node_name: 'Float64Array', edge_name: 'state' },
9394
]
94-
},
95+
}
96+
], { loose: true });
97+
98+
state.validateSnapshotNodes('Node / QuicClientSession', [
9599
{
96100
children: [
97101
{ node_name: 'QuicClientSession', edge_name: 'wrapped' },
98-
{ node_name: 'Node / QuicCryptoContext',
99-
edge_name: 'crypto_context' },
102+
{ node_name: 'Node / rx_secret', edge_name: 'rx_secret' },
103+
{ node_name: 'Node / tx_secret', edge_name: 'tx_secret' },
100104
{ node_name: 'Node / HistogramBase', edge_name: 'crypto_rx_ack' },
101105
{ node_name: 'Node / HistogramBase',
102106
edge_name: 'crypto_handshake_rate' },
103107
{ node_name: 'Node / Timer', edge_name: 'retransmit' },
104108
{ node_name: 'Node / Timer', edge_name: 'idle' },
105109
{ node_name: 'Node / QuicBuffer', edge_name: 'sendbuf' },
106110
{ node_name: 'Node / QuicBuffer', edge_name: 'txbuf' },
111+
{ node_name: 'Node / peer_handshake', edge_name: 'peer_handshake' },
107112
{ node_name: 'Float64Array', edge_name: 'recovery_stats_buffer' },
108113
{ node_name: 'BigUint64Array', edge_name: 'stats_buffer' },
109114
{ node_name: 'Node / current_ngtcp2_memory',
110115
edge_name: 'current_ngtcp2_memory' },
111-
{ node_name: 'Node / streams', edge_name: 'streams' },
116+
{ node_name: 'Node / QuicBuffer', edge_name: 'handshake' },
112117
{ node_name: 'Node / std::basic_string', edge_name: 'alpn' },
113118
{ node_name: 'Node / std::basic_string', edge_name: 'hostname' },
114119
{ node_name: 'Float64Array', edge_name: 'state' },
115120
]
116121
}
117122
], { loose: true });
118123

119-
state.validateSnapshotNodes('Node / QuicCryptoContext', [
120-
{
121-
children: [
122-
{ node_name: 'Node / rx_secret', edge_name: 'rx_secret' },
123-
{ node_name: 'Node / tx_secret', edge_name: 'tx_secret' },
124-
{ node_name: 'Node / QuicBuffer', edge_name: 'initial_crypto' },
125-
{ node_name: 'Node / QuicBuffer',
126-
edge_name: 'handshake_crypto' },
127-
{ node_name: 'Node / QuicBuffer', edge_name: 'app_crypto' },
128-
]
129-
}
130-
], { loose: true });
131-
132124
session.destroy();
133125
server.close();
134126
}));

0 commit comments

Comments
 (0)