-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
In #60105 (comment), @marten-seemann wrote the text below. Filing a separate proposal for this.
After playing around with this API in quic-go for the last week, and writing some tests where the application stores random data und one that uses session IDs, here's what I've found:
First of all, it works: The QUIC stack can store the QUIC transport parameters (and other connection parameters, such as the RTT) in the session ticket. That's great news!
I'd like to propose a small change to the API though: SessionState
currently has an Extra []byte
field, which the application can use to store application-level information with the session ticket. This is exactly what the QUIC stack does for the transport parameters.
However, the QUIC stack might not be the only one that's interested in using that slice to store additional information. For example, the HTTP/3 layer also needs to store certain values in the session ticket (see Section 7.2.4.2 of RFC 9114). Other implementations running on top of QUIC will probably want to do the same, and there could be multiple layers that want to do that.
This is pretty inconvenient, since at the time the WrapSession
callback is called for the application, the QUIC layer will already have filled the Extra
slice. Now the application will have to take care of adding its data into the same slice, in a way that allows it to extract that information in the UnwrapSession
callback later, and then restore the data before passing it on to the QUIC layer's UnwrapSession
callback.
Most likely, this means coming up with some kind of serialization format. It's possible, but every layer that wants to store information in the session ticket will have to invent its own way of doing that. Doing that in a forwards-compatible way most likely also means adding a versioning scheme...
What if we made it more explicit that this is a stack that every layer in the application can push to (on Wrap
) and pop from (on Unwrap
):
type SessionState struct {
// not exported
// PushExtra would append to this slice.
// PopExtra would pop the last element of this slice.
extra [][]byte
}
// PushExtra adds some extra information to the session state.
// This information is ignored by crypto/tls, but is encoded by [SessionState.Bytes]
// and parsed by [ParseSessionState].
//
// This allows [Config.UnwrapSession]/[Config.WrapSession] and
// [ClientSessionCache] wrappers to store and retrieve additional data.
func (SessionState) PushExtra([]byte)
// PopExtra removes extra information from the session state.
func (SessionState) PopExtra() (_ []byte, ok bool)
Any layer of the application (incl. the QUIC stack) would call PushExtra
in their WrapSession
callback, and retrieve that data saved using PopExtra
in UnwrapSession
. As today, serializing this field would be handled by crypto/tls, it's just that now we're serialzing a [][]byte
instead of a []byte
.
Metadata
Metadata
Assignees
Type
Projects
Status