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

Initial size of dynamic table #1530

Closed
martinthomson opened this issue Jul 6, 2018 · 19 comments
Closed

Initial size of dynamic table #1530

martinthomson opened this issue Jul 6, 2018 · 19 comments
Labels
-qpack design An issue that affects the design of the protocol; resolution requires consensus. has-consensus An issue that the Chairs have determined has consensus, by canvassing the mailing list.

Comments

@martinthomson
Copy link
Member

The draft doesn't say what the default should be. I think that it should be the value of the setting, which would be more efficient than the only sensible alternative (that is, 0). I don't see many encoders using less than the full table size for QPACK.

@martinthomson martinthomson added design An issue that affects the design of the protocol; resolution requires consensus. -qpack labels Jul 6, 2018
@MikeBishop
Copy link
Contributor

MikeBishop commented Jul 6, 2018

Section 4 says:

QPACK defines two settings which are included in the HTTP/QUIC SETTINGS frame.

SETTINGS_HEADER_TABLE_SIZE (0x1):
An integer with a maximum value of 2^30 - 1. The default value is 4,096 bytes. See (TODO: reference PR#1357) for usage.

Now, that TODO clearly needs a fix, but I'm not clear what's missing on this issue,

@martinthomson
Copy link
Member Author

That's a default value for the setting, but there is a starting value for the dynamic table size (prior to any size update instructions). What is that? Sorry for not being clearer.

@MikeBishop
Copy link
Contributor

MikeBishop commented Jul 9, 2018

Ah, I see. So the receiver has declared a maximum of 4KB, but if the encoder doesn't specify a size before sending instructions, what is the table size at that point?

My initial inclination matched yours, to say that it's the receiver's declared maximum, so that the encoder only needs to speak to reduce it. But there's a wrinkle: In 0-RTT, we assume the previous max; server can't accept 0-RTT if it's going to go lower, but can still increase its value when it sends the SETTINGS frame. That means either the server has to detect whether particular instructions were sent before or after the handshake completed and change the implicit table size, or there's a nasty corner case when the client thinks it has overflowed the table but the server thinks it hasn't.

HPACK requires the size change instruction to be the first instruction of the first block following the change; I'd honestly never thought about whether that requires a size change to be the first instruction of the first header block sent on a connection. Does it?

I think it has to be zero, and require the encoder to declare the size it intends to use.

@MikeBishop
Copy link
Contributor

Ugh. Actually, it's worse than that -- the server is allowed to tolerate violations during 0-RTT, so it could actually reduce the max table size once the SETTINGS frame arrives.

@martinthomson
Copy link
Member Author

If the server has to remember what value was associated with 0-RTT, can't we agree on that?

That is, if the client attempts 0-RTT and the server accepts it, the value is set to the 0-RTT value. We require that both peers remember the value from before, as we agreed in Montreal, so that's easy.

If 0-RTT is rejected, then it's a full handshake and they can all use the 1-RTT values.

In HPACK, we require the first header block that uses the dynamic table to include a table size update, because the table is assumed to start at 0 size (the default; also, settings might not be around when you send that header block). In QPACK, you always know how much space there is - even if it might later increase - so why not use that?

@dtikhonov
Copy link
Member

What if we have a fixed 0-RTT value? That is, if the server is willing to accept 0-RTT connections, its dynamic table size is at least $SOME_VALUE. This value can be increased in SHLO.

@martinthomson
Copy link
Member Author

@dtikhonov, that's exactly what is being proposed. $SOME_VALUE is determined by SETTINGS from the previous connection and new SETTINGS can be sent to increase that value.

I don't think that we should fix a value in the spec, if that is what you were implying.

@dtikhonov
Copy link
Member

I did mean a fixed value in the spec.

@martinthomson
Copy link
Member Author

I don't think that we could possibly agree on a value to standardize here. Servers and clients already have to remember things; I don't think that's a problem here.

@kazuho
Copy link
Member

kazuho commented Aug 7, 2018

@martinthomson

That is, if the client attempts 0-RTT and the server accepts it, the value is set to the 0-RTT value. We require that both peers remember the value from before, as we agreed in Montreal, so that's easy.

+1.

Having the same rule as we have for other limits (e.g. initial_max_bidi_streams) leads to less confusion.

@MikeBishop
Copy link
Contributor

While I do think that having the table initialize to zero and requiring an explicit size change from the encoder is probably the least bug-prone, I'm willing to save the two bytes and specify that the table begins at the decoder's maximum permitted size as of... whenever.

@dtikhonov
Copy link
Member

So the text in #1642 looks fine, but I would like a clarification (or confirmation): Is the 0-RTT dynamic table size presumed by the client implicit? That is, the client says: "let's use the table size we used before -- you know the value I mean!"

In that case, how can the server ever reduce its advertized table size without rejecting all 0-RTTs for a period of time?

@kazuho
Copy link
Member

kazuho commented Aug 9, 2018

In that case, how can the server ever reduce its advertized table size without rejecting all 0-RTTs for a period of time?

TLS session ticket has (or should have) a space in which you can store arbitrary data.

So generally speaking, a QUIC stack will store TP, table size, etc. in the session ticket. When it receives a session ticket, the stack consults those variables, and either adopts those variables and accept 0-RTT, or send a new set of settings at the same time rejecting 0-RTT.

@dtikhonov
Copy link
Member

I see. This is very helpful. Thank you!

@mirjak
Copy link
Contributor

mirjak commented Aug 9, 2018

That should probably be documented somewhere... applicability statement?

@MikeBishop
Copy link
Contributor

It's a requirement of the TLS implementation, not an applicability consideration for protocols that might want to use QUIC, so I'd be more inclined to see it called out in the TLS draft. It seems to belong in the more general category of "TLS stacks used for QUIC require the following features which aren't necessarily required for TLS/TCP".

Note that it's #1641 that extends that behavior to the HTTP settings as well as the QUIC transport parameters, so that part is not in the doc yet.

@kazuho
Copy link
Member

kazuho commented Aug 9, 2018

Note also that while we have two mechanisms for communicating the states of the previous connection (i.e. TLS session ticket and QUIC token), the latter cannot be used for this purpose because tokens are not protected by the handshake. An attacker can mount a cut-and-paste attack to bind a token obtained from a different connection to the victims handshake.

@martinthomson
Copy link
Member Author

@kazuho is right. The token needs to carry its own authentication, but that isn't incorporated into TLS. We should mention that explicitly.

Though you could pack stuff into a token and then authenticate it by adding a hash of that data to the session ticket...

@mirjak
Copy link
Contributor

mirjak commented Aug 10, 2018

What I was talking about for the applicability statement was the fact that you can use the session ticket to store information (e.g. TP) if you don't want to/can't store them at the server.

@mnot mnot added the has-consensus An issue that the Chairs have determined has consensus, by canvassing the mailing list. label Mar 5, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-qpack design An issue that affects the design of the protocol; resolution requires consensus. has-consensus An issue that the Chairs have determined has consensus, by canvassing the mailing list.
Projects
None yet
Development

No branches or pull requests

6 participants