Navigation Menu

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

HTTP/2 non flow controlled frames ingest limits #3998

Open
Scottmitch opened this issue Jul 17, 2015 · 3 comments
Open

HTTP/2 non flow controlled frames ingest limits #3998

Scottmitch opened this issue Jul 17, 2015 · 3 comments
Assignees

Comments

@Scottmitch
Copy link
Member

Flow control allows us to limit the amount of data we ingest for flow controlled frames. However for frames that are not subject to flow control we do not have any such limits for the amount of data we ingest. Should we have some controls or limits for the amount of data we ingest for non flow controlled frames? For example a simplistic peer (or many peers) that has a large amount of send bandwidth could (D)DoS us with control frames (i.e. PING) and never reading any responses.

@Scottmitch
Copy link
Member Author

@ejona86 - You previously pointed out (#3783 (comment)) that auto_read must be on, but I'm wondering what other options we have to protect against traffic from control frames. I guess limiting what we read, or potentially closing the connection are the 2 options that come to mind. WDYT?

@ejona86
Copy link
Member

ejona86 commented Jul 17, 2015

@Scottmitch, hmm... Okay, let me think through this aloud.

If we have a pretty full write queue (of control messages), let's say we stop reading. This isn't discernible from the HTTP/2 semantic level because anything we sent would be queued anyway. So it would only impact the peer's ability to send on the TCP connection.

However, there could still be sent frames en route to the peer, including something like PING. When the peer then tries to ack the PING it could determine its queue is too full and stop reading. Deadlock.

What would fill up the write queue though, in "normal" operation? HEADERS could easily do it if issued many requests at once, especially since a naïve implementation would queue such a frame immediately, independent of the outbound buffer. That is only in the client->server direction though.

How about server->client? I can't come up with something offhand. A bunch of WINDOW_UPDATES for different streams all at once seems highly unlikely. Maybe the server is overloaded and times out a bunch of streams with RST_STREAM? Doesn't seem like enough. Maybe just stopping reading does work... although deadlocks are hard to predict many times.

The HTTP/2 spec does permit detecting "suspicious" behavior and aborting the connection:

An endpoint MAY treat activity that is suspicious as a connection error (Section 5.4.1) of type ENHANCE_YOUR_CALM.

Maybe we limit the number of pending PING + SETTING acks to something "insane" like "100" or "1000"? (When choosing the number, we do have to consider internal fragmentation of ByteBuffers causing more memory usage than the raw written byte count.) If it is exceeded, we fail with ENHANCE_YOUR_CALM.

I was thinking of limiting RST_STREAM to ~1 per stream. But that is vulnerable to: HEADERS (stream1), RST_STREAM (stream1), DATA (stream1) (causes server to send RST_STREAM), HEADERS (stream2), ...

I don't have a clear answer.

@Scottmitch Scottmitch self-assigned this Jul 17, 2015
@Scottmitch
Copy link
Member Author

@normanmaurer - Any thoughts?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants