Subject: ALPN and QUIC versions

From: Martin Duke <[email-masked]>
Date: Wed, 19 May 2021 08:26:58 -0700

There appears to be an under-examined sentiment in this WG that the 'h3'
ALPN specifically indicates QUIC version 1. The only spec explicitly
stating it, that I can find, is the applicability draft, and I've
filed an issue
against it <https://github.com/quicwg/ops-drafts/issues/360> [1]. I might
be in the rough here, but I'd like to push back on this design during WGLC
in case others share my concerns.

[TL;DR one ALPN per QUIC version will not scale with many versions and we
should do something else]

quic-http says "HTTP/3 relies on QUIC version 1 as the underlying
transport. The use of other QUIC transport versions with HTTP/3 MAY be
defined by future specifications.," which to me is not quite the same thing
as saying we need a new ALPN.

For the QUICv2 draft there has been some discussion
<https://github.com/martinduke/draft-duke-quic-v2/issues/5> of what the
correct way <https://github.com/martinduke/draft-duke-quic-v2/pull/6> to
specify support for HTTP/3 is. [2,3]

I'm fine with the quic-http wording, but I dislike the text in the
applicability draft. There are a few ways we could actually design the
interaction of applications and versions:

1) As stated in the applicability draft, the ALPN includes the QUIC
version. Then every new version document has to review the set of
QUIC-specific ALPN codes and register new ALPNs. As these version numbers
are 32 bit integers and may not simply increment up from 1, ALPN codes will
often look like h3-0x4384abc0, doq-0x4384abc0 [4], etc. Similarly, each new
application of QUIC has to review the set of QUIC versions and register new
ALPNs for each version. This has the advantage of reducing the need for
version negotiation, but it's not scalable if there are a lot of versions
and applications. The ALPN registry will essentially have a matrix of
applications and QUIC versions with the combination that signifies each.

I imagine most QUIC implementation APIs would present an interface for an
application to declare its ALPNs. I'm not sure how that implementation
easily deploys new versions (or deprecates old ones) if all the apps then
have to change, unless it's mutating the ALPN from an application-provided
root. That seems error-prone.

2) A draft with a new QUIC version MUST formally update any QUIC
application RFC for which it wants to use the same ALPN. Application RFCs
would say which versions can transport them at the time of writing without
a formal update. So to find the available QUIC versions for a given
application RFC, one could see the versions listed in that RFC (which
obviously predate the application) and then note in the header which RFCs
update it (all the compatible versions released since). Mike Bishop suggested
this course of action
<https://github.com/martinduke/draft-duke-quic-v2/pull/6> in [3]. This
property is somewhat convenient, but again, I don't think it scales
incredibly well: if there are many versions, the front page of HTTP/3 could
be filled with RFCs that update it, merely because they say "you can use h3
with this"

3) Add a column to the IANA ALPN Registry
<https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids>
[5] that specifically lists the compatible QUIC versions. For most current
entries (which are not QUIC-compatible), this would be empty. New
application or version RFCs could simply update the registry, which will
scale somewhat better than (1) and still be easily discoverable. I am happy
to write a short draft to change the registry if that's how we want to
proceed.

4) There is no formal trail of linkages. New version RFCs should say what
apps they support (possibly as generic as "all v1 applications work with
the new version") and applications should say if (a) the list of usable
versions is other than the full known set and (b) what properties it needs
from a QUIC version to operate. This is the path I took in a v2 PR
<https://github.com/martinduke/draft-duke-quic-v2/pull/6> [3], which has no
official standing whatsoever. This makes the forensics to obtain the full
list of usable versions quite a bit harder, but won't explode the ALPN
registry or the front page of HTTP/3.

There are probably other solutions I haven't thought of. I have
purposefully ignored the whole question of provisional and experimental
versions to keep this at a manageable length.

As you might tell, I would prefer (3) or (4). I would like to confirm I am
in the rough before we ship the applicability draft that [informatively]
mandates (1).

Martin

[1] https://github.com/quicwg/ops-drafts/issues/360
[2] https://github.com/martinduke/draft-duke-quic-v2/issues/5
[3] https://github.com/martinduke/draft-duke-quic-v2/pull/6
[4] I'm happy to bikeshed on decimals vs. hex, if we choose this option.
[5]
https://www.iana.org/assignments/tls-extensiontype-values/tls-extensiontype-values.xhtml#alpn-protocol-ids

---

From: Spencer Dawkins at IETF <[email-masked]>
Date: Wed, 19 May 2021 16:12:07 -0500

Hi, Martin,

On Wed, May 19, 2021 at 10:27 AM Martin Duke <[email-masked]>
wrote:

> stating it, that I can find, is the applicability draft, and I've filed an issue

Thank you for raising this question now.

> root. That seems error-prone.

I agree with your reasoning here, but in addition, doesn't that require
either (1) implementations to support old QUIC versions basically forever,
or (2) deployed applications to be updated to specify a new ALPN in order
to retire old QUIC versions?

When we were chartering TAPS, one of the major reasons was to stop
requiring application updates to take advantage of new transport protocols.
I know this isn't quite the same thing, but I'm not understanding why
requiring applications to be updated to specify a new ALPN for a backwards
compatible version of QUIC (so, little or no benefit for the application)
would be a GOOD thing.

> to write a short draft to change the registry if that's how we want to

ISTM that this is the best choice. If QUIC versions bloom like flowers,
maintaining the ALPN-QUIC version linkage in an IANA registry is going to
scale better than any of the other choices (or, perhaps, will scale less
badly, but that's roughly the same thing).

If QUIC versions don't bloom like flowers, this would still work.

> <https://github.com/martinduke/draft-duke-quic-v2/pull/6> [3], which has
> no official standing whatsoever. This makes the forensics to obtain the
> full list of usable versions quite a bit harder, but won't explode the ALPN

"[informatively] mandates". <chuckles to himself while planning an April 1
RFC updating BCP14>

Best,

Spencer

---

From: Martin Duke <[email-masked]>
Date: Wed, 19 May 2021 14:22:13 -0700

Hi Spencer,

> to retire old QUIC versions?

I believe that is correct (hence my parenthetical about deprecating old
versions)

> compatible version of QUIC (so, little or no benefit for the application)

I agree!

---

From: Lucas Pardue <[email-masked]>
Date: Thu, 20 May 2021 01:08:44 +0100

Hi Martin

Speaking as an individual. There's a lot to consider here, I don't have a
complete response.

For a start, I think there are ways to rephrase the applicability draft
text to get over some thorniness - seems I'm on the hook to do that,
reviews will will welcome.

To respond to one of your suggestions

> registry or the front page of HTTP/3.

I might grade incompatible breaking versions on at least two criteria.
First, is the wire image the same? Second, are the protocol feature changes
that break the contract with upper layers, which would cover removing
features, changing features in ways that break dependent behaviour, adding
features that break dependent behaviour.

Such a grading exercise would appear to be a useful function of the QUIC WG
in the long run. What I mean by this is that (hypothetically) we should
encourage versions to state if their compatibility with other versions is
breaking or non-breaking. The QUIC version IANA table could, for example,
codify some of this.
The group has the expertise to assess such claims and the desire to avoid
version relationship explosion in breadth or depth (I.e. we would heavily
normalize).

QUIC extensions could state the known (at the time of writing) version(s)
that they extend. To keep it simple, they'd just need to state the earliest
registered version on each breaking version. We assume that non-breaking
versions published by the IETF all work. A single QUIC extension document
can define how it extends several breaking QUIC versions. We have a similar
situation right now when defining logically equivalent behavioral
extensions that need to work over H1, H2 and H3.

Application protocols could also state known (at the time of writing)
version(s) that they run over. Same as above.

When future breaking QUIC versions are published, extension and application
protocols can respond. Update documents could be effectively no-op, require
major/minor surgery, or state explicitly that a version is not supported if
they help the strong need to.
To make this activity easier, both extensions and application protocols
(and their extensions!) would benefit from stating the QUIC protocol
features that they depend on. Reviewing those statements is likely a
service the QUIC WG should provide to other groups.

I think this possibly leads to a hybrid option 4, where the ALPN registry
has a column that lists only breaking QUIC versions. And we don't mandate
any rules on the number of versions that a token can relate to.

Cheers
Lucas