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

http2: implement maxSessionMemory #17967

Closed
wants to merge 1 commit into from

Conversation

jasnell
Copy link
Member

@jasnell jasnell commented Jan 3, 2018

The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
Http2Stream sessions will be rejected with an
ENHANCE_YOUR_CALM error and existing Http2Stream
instances that are still receiving headers will be
terminated with an ENHANCE_YOUR_CALM error.

@nodejs/http2 (@mcollina in particular)

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

http2

@jasnell jasnell added the http2 Issues or PRs related to the http2 subsystem. label Jan 3, 2018
@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. lib / src Issues and PRs related to general changes in the lib or src directory. labels Jan 3, 2018
@jasnell
Copy link
Member Author

jasnell commented Jan 3, 2018

Copy link
Member

@mcollina mcollina left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

// Important: The maxSessionMemory option in javascript is expressed in
// terms of MB increments (i.e. the value 1 == 1 MB)
if (flags & (1 << IDX_OPTIONS_MAX_SESSION_MEMORY)) {
SetMaxSessionMemory(buffer[IDX_OPTIONS_MAX_SESSION_MEMORY] * 1e6);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that case you really should be specifying that you 1 MB is one million bytes, not 2^10 bytes ;)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@addaleax ... sorry, I'm being a bit thick... can you clarify the specific change? comment or code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jasnell Sorry, missed the notification – I meant, for some people 1 MB means 1.000.000 bytes, and for some it means 1.048.576 bytes, so it would be good to have disambiguated this in the documentation :)

src/node_http2.h Outdated
@@ -1121,6 +1164,10 @@ class Http2Session::Http2Ping : public AsyncWrap {

size_t self_size() const override { return sizeof(*this); }

uint64_t cost() const {
return sizeof(Http2Session::Http2Ping);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think these cost() methods are essentially exactly the same as self_size(), so it might be nicer to keep using the existing methods…?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was considering that, kept them separate for now in case there were other bits that needed to be accounted for at some point. For instance, the cost() of a settings frame is the size of the object + the number of settings included.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For instance, the cost() of a settings frame is the size of the object + the number of settings included.

I think that’s a bug in the self_size() methods for settings then – we’re generally not very strict about self_size() being accurate, but as long as the semantics are “the size of the memory owned by this object”, they seem pretty much identical for both methods?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good point... hmm ok

uint64_t GetCurrentSessionMemory() {
uint64_t total = current_session_memory_ + sizeof(Http2Session);
total += nghttp2_session_get_hd_deflate_dynamic_table_size(session_);
total += nghttp2_session_get_hd_inflate_dynamic_table_size(session_);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m wondering what the cost of these calls is, since they can’t be inlined & this function is called quite a few times as far as I can tell? Did you try to measure that? (Not a blocker, I think this feature is worth it either way)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, haven't benchmarked it yet.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One way we can limit the impact here is to capture the inbound dynamic table size at the completion of a headers frame, and the outbound dynamic size after sending a headers frame, then just add the static values.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(note that doing so relaxes one of the protections included here that keeps headers within a single HEADERS frame from blowing the memory limit)

@jasnell
Copy link
Member Author

jasnell commented Jan 5, 2018

The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.
jasnell added a commit that referenced this pull request Jan 5, 2018
The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.

PR-URL: #17967
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@jasnell
Copy link
Member Author

jasnell commented Jan 5, 2018

Landed in 882e7ef.

@jasnell jasnell closed this Jan 5, 2018
MylesBorins pushed a commit to jasnell/node that referenced this pull request Jan 9, 2018
The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.

PR-URL: nodejs#17967
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
MylesBorins pushed a commit that referenced this pull request Jan 9, 2018
The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.

Backport-PR-URL: #18050
PR-URL: #17967
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@MylesBorins MylesBorins mentioned this pull request Jan 10, 2018
MylesBorins added a commit that referenced this pull request Jan 10, 2018
Notable change:

* async_hooks:
  - deprecate AsyncHooks Sensitive API and runInAsyncIdScope. Neither
    API were documented. (Andreas Madsen)
    #16972
* deps:
  - update nghttp2 to 1.29.0 (James M Snell)
    #17908
  - upgrade npm to 5.6.0 (Kat Marchán)
    #17535
  - cherry-pick 50f7455 from upstream V8 (Michaël Zasso)
    #16591
* events:
  - remove reaches into _events internals (Anatoli Papirovski)
    #17440
* http:
  - add rawPacket in err of `clientError` event (XadillaX)
    #17672
* http2:
  - implement maxSessionMemory (James M Snell)
    #17967
  - add initial support for originSet (James M Snell)
    #17935
  - add altsvc support (James M Snell)
    #17917
  - perf_hooks integration (James M Snell)
    #17906
* net:
  - remove Socket.prototype.write (Anna Henningsen)
    #17644
  - remove Socket.prototype.listen (Ruben Bridgewater)
    #13735
* repl:
  - show lexically scoped vars in tab completion (Michaël Zasso)
    #16591
* stream:
  - rm {writeable/readable}State.length (Calvin Metcalf)
    #12857
  - add flow and buffer properties to streams (Calvin Metcalf)
    #12855
* util:
  - allow wildcards in NODE_DEBUG variable (Tyler)
    #17609
* zlib:
  - add ArrayBuffer support (Jem Bezooyen)
    #16042
* Addedew collaborator**
  - [starkwang](https://github.com/starkwang) Weijia Wang
* Addedew TSC member**
  - [danbev](https://github.com/danbev) Daniel Bevenius

PR-URL: #18069
MylesBorins pushed a commit that referenced this pull request Jan 10, 2018
The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.

Backport-PR-URL: #18050
PR-URL: #17967
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
MylesBorins added a commit that referenced this pull request Jan 10, 2018
Notable change:

* async_hooks:
  - deprecate AsyncHooks Sensitive API and runInAsyncIdScope. Neither
    API were documented. (Andreas Madsen)
    #16972
* deps:
  - update nghttp2 to 1.29.0 (James M Snell)
    #17908
  - upgrade npm to 5.6.0 (Kat Marchán)
    #17535
  - cherry-pick 50f7455 from upstream V8 (Michaël Zasso)
    #16591
* events:
  - remove reaches into _events internals (Anatoli Papirovski)
    #17440
* http:
  - add rawPacket in err of `clientError` event (XadillaX)
    #17672
* http2:
  - implement maxSessionMemory (James M Snell)
    #17967
  - add initial support for originSet (James M Snell)
    #17935
  - add altsvc support (James M Snell)
    #17917
  - perf_hooks integration (James M Snell)
    #17906
  - Refactoring and cleanup of Http2Session and Http2Stream destroy
    (James M Snell) #17406
* net:
  - remove Socket.prototype.write (Anna Henningsen)
    #17644
  - remove Socket.prototype.listen (Ruben Bridgewater)
    #13735
* repl:
  - show lexically scoped vars in tab completion (Michaël Zasso)
    #16591
* stream:
  - rm {writeable/readable}State.length (Calvin Metcalf)
    #12857
  - add flow and buffer properties to streams (Calvin Metcalf)
    #12855
* util:
  - allow wildcards in NODE_DEBUG variable (Tyler)
    #17609
* zlib:
  - add ArrayBuffer support (Jem Bezooyen)
    #16042
* Addedew collaborator**
  - [starkwang](https://github.com/starkwang) Weijia Wang
* Addedew TSC member**
  - [danbev](https://github.com/danbev) Daniel Bevenius

PR-URL: #18069
MylesBorins added a commit that referenced this pull request Jan 10, 2018
Notable change:

* async_hooks:
  - deprecate AsyncHooks Sensitive API and runInAsyncIdScope. Neither
    API were documented. (Andreas Madsen)
    #16972
* deps:
  - update nghttp2 to 1.29.0 (James M Snell)
    #17908
  - upgrade npm to 5.6.0 (Kat Marchán)
    #17535
  - cherry-pick 50f7455 from upstream V8 (Michaël Zasso)
    #16591
* events:
  - remove reaches into _events internals (Anatoli Papirovski)
    #17440
* http:
  - add rawPacket in err of `clientError` event (XadillaX)
    #17672
* http2:
  - implement maxSessionMemory (James M Snell)
    #17967
  - add initial support for originSet (James M Snell)
    #17935
  - add altsvc support (James M Snell)
    #17917
  - perf_hooks integration (James M Snell)
    #17906
  - Refactoring and cleanup of Http2Session and Http2Stream destroy
    (James M Snell) #17406
* net:
  - remove Socket.prototype.write (Anna Henningsen)
    #17644
  - remove Socket.prototype.listen (Ruben Bridgewater)
    #13735
* repl:
  - show lexically scoped vars in tab completion (Michaël Zasso)
    #16591
* stream:
  - rm {writeable/readable}State.length (Calvin Metcalf)
    #12857
  - add flow and buffer properties to streams (Calvin Metcalf)
    #12855
* util:
  - allow wildcards in NODE_DEBUG variable (Tyler)
    #17609
* zlib:
  - add ArrayBuffer support (Jem Bezooyen)
    #16042
* Addedew collaborator**
  - [starkwang](https://github.com/starkwang) Weijia Wang
* Addedew TSC member**
  - [danbev](https://github.com/danbev) Daniel Bevenius

PR-URL: #18069
@MylesBorins
Copy link
Contributor

This does not land cleanly on v8.x, could we get a backport?

kjin pushed a commit to kjin/node that referenced this pull request May 1, 2018
The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.

Backport-PR-URL: nodejs#18050
PR-URL: nodejs#17967
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
MylesBorins pushed a commit that referenced this pull request May 2, 2018
The maxSessionMemory is a cap for the amount of memory an
Http2Session is permitted to consume. If exceeded, new
`Http2Stream` sessions will be rejected with an
`ENHANCE_YOUR_CALM` error and existing `Http2Stream`
instances that are still receiving headers will be
terminated with an `ENHANCE_YOUR_CALM` error.

Backport-PR-URL: #18050
Backport-PR-URL: #20456
PR-URL: #17967
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
@MylesBorins MylesBorins mentioned this pull request May 2, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
c++ Issues and PRs that require attention from people who are familiar with C++. http2 Issues or PRs related to the http2 subsystem. lib / src Issues and PRs related to general changes in the lib or src directory.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants