Draft: draft-ietf-quic-version-negotiation

Commentary: Original version was defined as the version a client attempts prior to a VN packet . If there is a VN packet , I think that it is still possible to do a compatible upgrade from the version in the client 's second attempt . In that case , " original version " is n't the right term to use when talking about compatible upgrades . 
 We can sidestep this particular issue by removing the " unless ... " clause . That clause is n't helping because the client 's chosen version MUST already be present in the compatible versions list . However , this issue raises a good point : it 's possible for incompatible VN to happen and then be followed by compatible VN . We should clarify that this is allowed , and clearly define what the " original version " is in that scenario . 
 Consider the case where the client and server both support v1 and v2 and prefer v2 . In the current draft , if the client puts v1 in the long header and the server responds with v2 , that 's called " compatible version negotiation " . OTOH , if the client puts v2 in the long header and the server responds with v2 , that 's called , well , I 'm not quite sure what . I guess not negotiation ? I think a better way to think about this is that the client is sending an Initial that is compatible with both versions and so both of these cases are compatible version negotiation . 
 In the scenario where the client starts with v2 and the server responds with v2 , I think of that as just " creating a v2 connection " without compatible version negotiation involved . Let 's discuss this with the WG at IETF 113 .
QUIC does not provide a complete version negotiation mechanism but
instead only provides a way for the server to indicate that the
version the client offered is unacceptable.  This document describes
a version negotiation mechanism that allows a client and server to
select a mutually supported version.  Optionally, if the original and
negotiated version share a compatible first flight format, the
negotiation can take place without incurring an extra round trip.
The version-invariant properties of QUIC INV define a Version
Negotiation packet but do not specify how an endpoint reacts when it
receives one.  QUIC version 1 QUIC allows the server to use a Version
Negotiation packet to indicate that the version the client offered is
unacceptable, but doesn't allow the client to safely make use of that
information to create a new connection with a mutually supported
version.
QUIC does not provide a complete version negotiation mechanism but
instead only provides a way for the server to indicate that the
version the client chose is unacceptable.  This document describes a
version negotiation mechanism that allows a client and server to
select a mutually supported version.  Optionally, if the client's
chosen version and the negotiated version share a compatible first
flight format, the negotiation can take place without incurring an
extra round trip.
The version-invariant properties of QUIC INV define a Version
Negotiation packet but do not specify how an endpoint reacts when it
receives one.  QUIC version 1 QUIC allows the server to use a Version
Negotiation packet to indicate that the version the client chose is
unacceptable, but doesn't allow the client to safely make use of that
information to create a new connection with a mutually supported
version.
The client initiates a QUIC connection by sending a first flight of
QUIC packets with a long header to the server INV.  We'll refer to
the version of those packets as the "original version".  The client's
first flight includes Version Information (see vers-info) which will
be used to optionally enable compatible version negotation (see
compat-vn), and to prevent version downgrade attacks (see downgrade).
Upon receiving this first flight, the server verifies whether it
knows how to parse first flights from the original version.  If it
does not, then it starts incompatible version negotiation, see
incompat-vn.  If the server can parse the first flight, it can either
establish the connection using the original version, or it MAY
attempt compatible version negotiation, see compat-vn.
The client initiates a QUIC connection by choosing an initial version
and sending a first flight of QUIC packets with a long header to the
server INV.  The client's first flight includes Version Information
(see vers-info) which will be used to optionally enable compatible
version negotation (see compat-vn), and to prevent version downgrade
attacks (see downgrade).  We'll refer to the version of the very
first packets the client sends as the "original version" and the
version of the first packets the client sends in a given QUIC
connection as the "client's chosen version".
Upon receiving this first flight, the server verifies whether it
knows how to parse first flights from the original version.  If it
does not, then it starts incompatible version negotiation, see
incompat-vn, which causes the client to initiate a new connection
with a different version.  For instance, if the client initiates a
connection with version A and the server starts incompatible version
negotiation and the client then initiates a new connection with
version B, we say that the first connection's client chosen version
is A, the second connection's client chosen version is B, and the
original version for the entire sequence is A.
If the server can parse the first flight, it can either establish the
connection using the client's chosen version, or it MAY select any
other compatible version, as described in compat-vn.
When the server can parse the client's first flight using the
original version, it can extract the client's Version Information
structure (see vers-info).  This contains the list of versions that
the client knows its first flight is compatible with.
If the server supports one of the client's compatible versions, and
the server also knows that the original version is compatible with
this version, and the client's first flight is compatible with this
version, then the server converts the client's first flight to that
version and replies to the client as if it had received the converted
first flight.  Note that this conversion process cannot fail by
definition of the first flight being compatible.  The version used by
the server in its reply is refered to as the "negotiated version".
The server MUST NOT reply with a version that is not present in the
client's compatible versions, unless it is the original version.
Clients will be made aware of compatible version negotiation by
seeing a change in the QUIC long header Version field.  It is
possible for the server to initially send packets with the original
version before switching to the negotiated version (for example, this
can happen when the client's Version Information structured spans
multiple packets; in that case the server might acknowledge the first
packet in the original version and later switch to a different
negotiated version).
When the server can parse the client's first flight using the
client's chosen version, it can extract the client's Version
Information structure (see vers-info).  This contains the list of
versions that the client knows its first flight is compatible with.
In order to perform compatible version negotiation, the server MUST
select one of these versions that (1) it supports and (2) it knows
the client's chosen version to be compatible with.  Once the server
has selected a version, termed the "negotiated version", it then
attempts to convert the client's first flight into that version, and
replies to the client as if it had received the converted first
flight.
If those formats are identical, as in cases where the negotiated
version is the same as the client's chosen version, then this will be
the identity transform.  If the first flight is correctly formatted,
then this conversion process cannot fail by definition of the first
flight being compatible; if the server is unable to convert the first
flight, it MUST abort the handshake.
Clients can determine the server's negotiated version by examining
the QUIC long header Version field.  It is possible for the server to
initially send packets with the client's chosen version before
switching to the negotiated version (for example, this can happen
when the client's Version Information structured spans multiple
packets; in that case the server might acknowledge the first packet
in the client's chosen version and later switch to a different
negotiated version).
If the server does not find a compatible version, it will use the
original version if it supports it, and if it doesn't then the server
will perform incompatible version negotiation instead, see incompat-
vn.
QUIC connections are shared state between a client and a server INV.
The compatible version negotiation mechanism defined in this document
(see compat-vn) is performed as part of a single QUIC connection;
that is, the packets with the original version are part of the same
connection as the packets with the negotiated version.
If the server does not find a compatible version (including the
client's chosen version), it will perform incompatible version
negotiation instead, see incompat-vn.
In this example, the client selected C from the server's Version
Negotiation packet, but the server preferred D and then selected it
from the client's offer.
QUIC connections are shared state between a client and a server INV.
The compatible version negotiation mechanism defined in this document
(see compat-vn) is performed as part of a single QUIC connection;
that is, the packets with the client's chosen version are part of the
same connection as the packets with the negotiated version.
If a future document wishes to define compatibility between two
versions that support retry, that document MUST specify how version
negotiation (both compatible and incompatible) interacts with retry
during a handshake that requires both.  For example, that could be
accomplished by having the server send a Retry packet in the original
version first thereby validating the client's IP address before
attempting compatible version negotiation.  If both versions support
authenticating Retry packets, the compatibility defition needs to
define how to authenticate the Retry in the negotiated version
handshake even though the Retry itself was sent using the original
version.
If a future document wishes to define compatibility between two
versions that support retry, that document MUST specify how version
negotiation (both compatible and incompatible) interacts with retry
during a handshake that requires both.  For example, that could be
accomplished by having the server send a Retry packet in the original
version first thereby validating the client's IP address before
attempting compatible version negotiation.  If both versions support
authenticating Retry packets, the compatibility defition needs to
define how to authenticate the Retry in the negotiated version
handshake even though the Retry itself was sent using the client's
chosen version.