summaryrefslogtreecommitdiff
path: root/src/node_http2.h
diff options
context:
space:
mode:
authorAnna Henningsen <anna@addaleax.net>2019-08-11 02:22:00 +0200
committerMichaƫl Zasso <targos@protonmail.com>2019-08-15 09:51:53 +0200
commit8a4a1931b8b98242abb590936c31f0c20dd2e08f (patch)
treec8bf3c88ae02fc925d8005559d46a45b1e0e477d /src/node_http2.h
parentba624b6766fffc11fc9a387feee58be2c5e1d8b8 (diff)
downloadandroid-node-v8-8a4a1931b8b98242abb590936c31f0c20dd2e08f.tar.gz
android-node-v8-8a4a1931b8b98242abb590936c31f0c20dd2e08f.tar.bz2
android-node-v8-8a4a1931b8b98242abb590936c31f0c20dd2e08f.zip
http2: pause input processing if sending output
If we are waiting for the ability to send more output, we should not process more input. This commit a) makes us send output earlier, during processing of input, if we accumulate a lot and b) allows interrupting the call into nghttp2 that processes input data and resuming it at a later time, if we do find ourselves in a position where we are waiting to be able to send more output. This is part of mitigating CVE-2019-9511/CVE-2019-9517. PR-URL: https://github.com/nodejs/node/pull/29122 Reviewed-By: Rich Trott <rtrott@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
Diffstat (limited to 'src/node_http2.h')
-rw-r--r--src/node_http2.h12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/node_http2.h b/src/node_http2.h
index 21e05157c1..9c032f02d1 100644
--- a/src/node_http2.h
+++ b/src/node_http2.h
@@ -337,6 +337,7 @@ enum session_state_flags {
SESSION_STATE_SENDING = 0x10,
SESSION_STATE_WRITE_IN_PROGRESS = 0x20,
SESSION_STATE_READING_STOPPED = 0x40,
+ SESSION_STATE_NGHTTP2_RECV_PAUSED = 0x80
};
typedef uint32_t(*get_setting)(nghttp2_session* session,
@@ -767,14 +768,15 @@ class Http2Session : public AsyncWrap, public StreamListener {
// Indicates whether there currently exist outgoing buffers for this stream.
bool HasWritesOnSocketForStream(Http2Stream* stream);
- // Write data to the session
- ssize_t Write(const uv_buf_t* bufs, size_t nbufs);
+ // Write data from stream_buf_ to the session
+ ssize_t ConsumeHTTP2Data();
void MemoryInfo(MemoryTracker* tracker) const override {
tracker->TrackField("streams", streams_);
tracker->TrackField("outstanding_pings", outstanding_pings_);
tracker->TrackField("outstanding_settings", outstanding_settings_);
tracker->TrackField("outgoing_buffers", outgoing_buffers_);
+ tracker->TrackFieldWithSize("stream_buf", stream_buf_.len);
tracker->TrackFieldWithSize("outgoing_storage", outgoing_storage_.size());
tracker->TrackFieldWithSize("pending_rst_streams",
pending_rst_streams_.size() * sizeof(int32_t));
@@ -833,6 +835,7 @@ class Http2Session : public AsyncWrap, public StreamListener {
}
void DecrementCurrentSessionMemory(uint64_t amount) {
+ DCHECK_LE(amount, current_session_memory_);
current_session_memory_ -= amount;
}
@@ -995,8 +998,11 @@ class Http2Session : public AsyncWrap, public StreamListener {
uint32_t chunks_sent_since_last_write_ = 0;
uv_buf_t stream_buf_ = uv_buf_init(nullptr, 0);
+ // When processing input data, either stream_buf_ab_ or stream_buf_allocation_
+ // will be set. stream_buf_ab_ is lazily created from stream_buf_allocation_.
v8::Global<v8::ArrayBuffer> stream_buf_ab_;
AllocatedBuffer stream_buf_allocation_;
+ size_t stream_buf_offset_ = 0;
size_t max_outstanding_pings_ = DEFAULT_MAX_PINGS;
std::queue<std::unique_ptr<Http2Ping>> outstanding_pings_;
@@ -1006,6 +1012,7 @@ class Http2Session : public AsyncWrap, public StreamListener {
std::vector<nghttp2_stream_write> outgoing_buffers_;
std::vector<uint8_t> outgoing_storage_;
+ size_t outgoing_length_ = 0;
std::vector<int32_t> pending_rst_streams_;
// Count streams that have been rejected while being opened. Exceeding a fixed
// limit will result in the session being destroyed, as an indication of a
@@ -1015,6 +1022,7 @@ class Http2Session : public AsyncWrap, public StreamListener {
// Also use the invalid frame count as a measure for rejecting input frames.
int32_t invalid_frame_count_ = 0;
+ void PushOutgoingBuffer(nghttp2_stream_write&& write);
void CopyDataIntoOutgoing(const uint8_t* src, size_t src_length);
void ClearOutgoing(int status);