Subject: Proposal for QUIC header

From: Martin Thomson <[email-masked]>
Date: Thu, 9 Feb 2017 15:42:52 +1100

As I go through the issues list, it appears that a lot of issues on
which we have consensus would benefit from a resolution to the header
format issue.  To that end, I have sketched out a proposal that I
think meets the various constraints we have.

I want to discuss this here before we embark on what could be a fairly
disruptive set of changes to the drafts.

(A copy of the following text can be found at
https://gist.github.com/martinthomson/744d04cbcec9be554f2f8e7bae2715b8
)
--

There are two forms of QUIC common header: long and short.  Long form packets
are used for the initial exchange - until both 1-RTT packet protection can be
started AND version negotiation is complete.  Short form packets carry the
bulk of the data.

This removes a lot of the flexibility that was the source of most of the
objections to the current format.  Fields are aligned on four octet boundaries.
All long-form header variations have the exact same form.  The connection ID is
in the same place in both short and long form.  The long form clearly
identifies the role of the sender in the first octet and it identifies the
packet as a QUIC packet.

The cost is that it makes occasional packets a little larger (the long header
is 20 octets, whereas the existing form uses between 14 and 19 octets
for initial
handshake packets).  This is an acceptable trade-off given that only a few of
these packets are ever exchanged on a connection.

It makes most packets (the short header) 12 octets where it is possible to
have 10 octet packets.  However, a 10 octet packet header assumes an 8 bit
packet number, this is 30.

# Long Header

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|S|Typ|  Next   |              Magic "uic"/"UIC"                |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                         Connection ID                         +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                            Version                            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Packet Number                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                       [Header Extensions]                   ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                           Payload                           ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

The first four octets:
* Octet 0: Special
  * Bit 7 (i.e., 0x80): SHORT_HEADER (set to 0 here)
  * Bit 6-5: Type
    * 11 - client packet
    * 10 - server packet
    * 01 - public reset
    * 00 - version negotiation
  * Bits 4-0: Next protocol
    * 0b10001 indicates that it is QUIC handshake data
    * 0b01111 indicates that it is QUIC 0-RTT data
    * other values mean that the payload following the packet number contains
     an IPv6-style extension header
* Octets 1-3: Magic (this can be short given that we will have a MAC as well)
  * 0x756963 for a client,
  * 0x554943 for a server

Note: A client packet starts with "quic", server starts with "QUIC",
0-RTT starts
with "ouic".

Note(2): We might consider the second set of 7 bits to be a single code space,
rather than use a 2+5 bit partitioning.  That gives us a bit more flexibility
and avoids meaningless combinations like public reset + 0-RTT.

The remainder of the packet layout is the same regardless of type, the
difference
being what rules for how to fill the values out and their semantics.

A client packet then contains:
* Octets 4-11: connection ID (initially all zeroes/random)
* Octets 12-15: version
* Octets 16-19: packet number (low 4 octets, starts at a random 32-bit value)
* Octets 20+: payload

Note: I'm not sure whether the client should pack the connection ID with random
values.  They would have no semantic value, though they might serve to provide
proof that the server received the packet if we require echoing, see below.

A server packet contains a connection ID:
* Octets 4-11: connection ID (server-selected value)
* Octets 12-15: version (echoed)
* Octets 16-19: packet number (low 4 octets, random 32-bit initial value)
* Octets 20+: payload

A version negotiation packet contains:
* Octets 4-11: connection ID (echoed)
* Octets 12-15: version received (echoed)
* Octets 16-19: packet number (echoed)
* Octets 20+: payload = version list

A public reset packet contains:
* Octets 4-11: connection ID (echoed)
* Octets 12-15: version (echoed)
* Octets 16-19: rejected packet number (echoed)
* Octets 20+: payload = authentication data

Echoing details from the packet in both version negotiation and provides return
routeability on version negotiation (#244), while maintaining a consistent
header shape for all packets.

These long-form packets are used for anything that doesn't have 1-RTT packet
protection and prior to the completion of version negotiation.  Once both
conditions are met, switch to sending short-form packets.  I haven't defined any
5/7-bit code for protected long-form packets, but that's easy to do if we need
to provide for them (see below for more on this).

## Extension headers

An 8-bit space (like IPv6) carries an identifier for the protocol extension.

Each header extension takes the form:
* Octet 1: next identifier
* Octet 2: length

Since only the lower 5 (or 7) bits of this space is accessible from the outset,
0x00 is reserved for a null extension header, allowing the full space to be
unlocked.  0x?a can be used for greasing.

I haven't talked to IP-layer people about whether they consider the IPv6 scheme
this is based on to be successful.  Either way, this should at least have plenty
of hardware support.

FWIW, I'm not sure that we need the complexity that this adds.  It's not clear
that there is a motivating use case.   However, on balance it's probably worth
putting something in for the moment.  If it turns out that we don't use it and
can't find even a potential use case, then removing it is simple enough.

That said, this form could be used to pack a TLS Finished into 1-RTT packets if
we define a 5- or 7-bit code for "small bit of handshake, followed by more",
after which we can include a 1-RTT payload.

# Short Header

```
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|S|K|                Packet Number (30)                         |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                         Connection ID                         +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
```

The short form header is defined to be specific to a version.  Anything
can change between protocol versions.

A short packet header - in this version - reserves two bits from the first
octet:
* SHORT_HEADER bit 7 (0x80) = 1,
* KEY_PHASE bit 6 (0x40) = 0 initially

The remainder of the first four octets contain the packet number.  30 bits
should be plenty.  If a need is found for more flags, those can steal upper
bits from the packet number.  (Frankly, I suspect that 14 bits might be
enough, but Ian was a little leery of that when I suggested it, and this
keeps the connection ID in the same place in every packet.)

The connection ID follows on the next 8 octets.

If we need more bits, then we can steal them from the packet number.

---

From: "Lubashev, Igor" <[email-masked]>
Date: Thu, 9 Feb 2017 14:28:19 +0000

Martin, I like how simple this looks now.  I few comments on this.

1. Long Header

The choice of names for Bit 6-5 Typ seem a bit confusing. Public Resets and Version Negotiation packets are also "server" or "client" packets. Also, 'Magic "uic"/"UIC"' is sufficient to tell the origin of the packet, so are distinct "server packet" / "client packet" types needed?

The "version negotiation" packet needs to have an echoed connection ID.  Is this a packet sent by the server in response to the initial packet from the client? If so, would we want to just echo a random connection ID there instead of selecting the connection ID? The packet number is also said to be echoed. Would not the sender of "version negotiation" packet want to use its own packet number?

2. Short Header

"Anything can change between protocol versions." I do not think this is correct. You at least ought to have [SHORT_HEADER bit 7 (0x80) = 1] for all versions. Otherwise, if some version were to define this bit=0 for "short header" packets, a restarting endpoint may get mightily confused by arriving packets belonging to previously legitimately negotiated QUIC connections.

Moreover, I think even more things may need to stay constant (like the location of the ConnectionID). Otherwise, you are likely to confuse an end point whose QUIC-speaking application is restarted into a newer (or older) version that does not support the previous QUIC version and, instead, supports a QUIC version where the ConnectionID has moved to another location in the header. I.e. that application may not be able to figure out that arriving QUIC packets do not belong to any of the connections it is aware of.

Both of the above may not be catastrophic (QUIC should be able to handle "internet noise"), but the behavior may result in the application causing some unintended reflected "internet noise" of its own.

- Igor

-----Original Message-----
From: Martin Thomson [mailto:[email-masked]] 
Sent: Wednesday, February 08, 2017 11:43 PM
To: IETF QUIC WG <[email-masked]>
Subject: Proposal for QUIC header

As I go through the issues list, it appears that a lot of issues on which we have consensus would benefit from a resolution to the header format issue.  To that end, I have sketched out a proposal that I think meets the various constraints we have.

I want to discuss this here before we embark on what could be a fairly disruptive set of changes to the drafts.

There are two forms of QUIC common header: long and short.  Long form packets are used for the initial exchange - until both 1-RTT packet protection can be started AND version negotiation is complete.  Short form packets carry the bulk of the data.

This removes a lot of the flexibility that was the source of most of the objections to the current format.  Fields are aligned on four octet boundaries.
All long-form header variations have the exact same form.  The connection ID is in the same place in both short and long form.  The long form clearly identifies the role of the sender in the first octet and it identifies the packet as a QUIC packet.

The cost is that it makes occasional packets a little larger (the long header is 20 octets, whereas the existing form uses between 14 and 19 octets for initial handshake packets).  This is an acceptable trade-off given that only a few of these packets are ever exchanged on a connection.

It makes most packets (the short header) 12 octets where it is possible to have 10 octet packets.  However, a 10 octet packet header assumes an 8 bit packet number, this is 30.

# Long Header

```
 0                   1                   2                   3

The first four octets:
* Octet 0: Special

Note: A client packet starts with "quic", server starts with "QUIC", 0-RTT starts with "ouic".

Note(2): We might consider the second set of 7 bits to be a single code space, rather than use a 2+5 bit partitioning.  That gives us a bit more flexibility and avoids meaningless combinations like public reset + 0-RTT.

The remainder of the packet layout is the same regardless of type, the difference being what rules for how to fill the values out and their semantics.

Note: I'm not sure whether the client should pack the connection ID with random values.  They would have no semantic value, though they might serve to provide proof that the server received the packet if we require echoing, see below.

Echoing details from the packet in both version negotiation and provides return routeability on version negotiation (#244), while maintaining a consistent header shape for all packets.

These long-form packets are used for anything that doesn't have 1-RTT packet protection and prior to the completion of version negotiation.  Once both conditions are met, switch to sending short-form packets.  I haven't defined any 5/7-bit code for protected long-form packets, but that's easy to do if we need to provide for them (see below for more on this).

## Extension headers

Since only the lower 5 (or 7) bits of this space is accessible from the outset,
0x00 is reserved for a null extension header, allowing the full space to be unlocked.  0x?a can be used for greasing.

I haven't talked to IP-layer people about whether they consider the IPv6 scheme this is based on to be successful.  Either way, this should at least have plenty of hardware support.

FWIW, I'm not sure that we need the complexity that this adds.  It's not clear
that there is a motivating use case.   However, on balance it's probably worth
putting something in for the moment.  If it turns out that we don't use it and can't find even a potential use case, then removing it is simple enough.

That said, this form could be used to pack a TLS Finished into 1-RTT packets if we define a 5- or 7-bit code for "small bit of handshake, followed by more", after which we can include a 1-RTT payload.

# Short Header

```
 0                   1                   2                   3

The short form header is defined to be specific to a version.  Anything can change between protocol versions.

The remainder of the first four octets contain the packet number.  30 bits should be plenty.  If a need is found for more flags, those can steal upper bits from the packet number.  (Frankly, I suspect that 14 bits might be enough, but Ian was a little leery of that when I suggested it, and this keeps the connection ID in the same place in every packet.)

---

From: Ryan Hamilton <[email-masked]>
Date: Thu, 9 Feb 2017 10:31:43 -0800

On Wed, Feb 8, 2017 at 8:42 PM, Martin Thomson <[email-masked]>
wrote:

> have 10 octet packets.

​In currently deployed QUIC, 1-RTT packets from the server to the client do
not have connection ID present. (This is because an endpoint tells the peer
how many connection​ ID bits it needs the peer to send. In the case of
clients, since they only have 1 connection on a given socket, the
connection ID is not needed.). These packets also typically have a 1 or 2
byte packet number. So the header ends up being:  1 byte public flags + 1
or 2 byte packet number for a total of 2-3 bytes. This new format seems to
be much larger.

> However, a 10 octet packet header assumes an 8 bit

I don't think I understand how to construct a 10 octet packet. Can you
elaborate?

> ​

> * Octets 20+: payload = version list

In order for the server to echo back the packet number, the server
obviously needs to be able parse the packet number. But if the packet
contains a version that the server does not support, it may well be the
case that the packet number layout may be different in the new version. So
I'm not sure it's possible to echo back the packet number.
​

> * Octets 20+: payload = authentication data

​Public reset packets are commonly sent when a server receives a packet for
a connection it does not have state for. (For example, a server restart or
a routing hiccup). In this case, the server is responding to a packet with
an unknown version and consequently and unknown packet number. So I'm not
sure it's possible to echo back the packet number.
​

---

From: Ian Swett <[email-masked]>
Date: Thu, 9 Feb 2017 14:57:32 -0500

Thanks for taking a crack at this.  I have a few high-level comments.

1) This implicitly requires the connection ID to always be stated, which as
Ryan said, inflates the packet header substantially from the status quo of
what we send server to client, which I'm not a fan of from a practical
perspective.  Equally importantly, I think we need to resolve the
conversation about privacy and connection IDs before we know whether we
should always be sending the connection ID.
2) I believe we may want to add packet number echo bit(#269
<https://github.com/quicwg/base-drafts/issues/269>) and possibly a loss
detection bit(#279 <https://github.com/quicwg/base-drafts/issues/279>) on
every packet.  I think it makes sense to resolve these before redesigning
the packet header, since I believe it would substantially change your
current design?
3) This proposes header extensions, which seems orthogonal to the header
redesign.  I'm not a fan of header extensions at the moment, but I think it
deserves a separate conversation.

So I would be biased towards getting some clarity on the connection id
privacy question as well as the #269 and #279 before attempting a holistic
redesign of the packet header.

On Thu, Feb 9, 2017 at 1:31 PM, Ryan Hamilton <[email-masked]> wrote:

> ​In currently deployed QUIC, 1-RTT packets from the server to the client
> do not have connection ID present. (This is because an endpoint tells the
> peer how many connection​ ID bits it needs the peer to send. In the case of
>> proof that the server received the packet if we require echoing, see
>> below.​
>
>
> ​Public reset packets are commonly sent when a server receives a packet
> for a connection it does not have state for. (For example, a server restart
> or a routing hiccup). In this case, the server is responding to a packet
> with an unknown version and consequently and unknown packet number. So I'm
> not sure it's possible to echo back the packet number.
> ​
>

---

From: Jana Iyengar <[email-masked]>
Date: Thu, 9 Feb 2017 12:42:05 -0800

Martin,

I like that you've separated the early handshake packet format from the
"common case" format -- there may be value in having that separation when
thinking about overhead and header formats (earlier versions of the
transport draft talked about Regular and Special packets, which may be
worth reconsidering.) That said, I think this proposal conflates three
things:
(i) it attempts to compress the header, in some cases
(ii) it changes the header in ways which have been suggested but without
consensus (connection ID, magic field)
(iii) it adds extensibility in ways that are not yet justified.

I think the proposal is useful in that it shows how the header might look
in a different world. But let's get consensus on what's reasonable to do
before figuring out how to do it. Specifically, as Ian notes, #269 and #279
are existing issues, and we need to discuss things like the magic header
field before adding them in (is there an issue for this?)

I propose parking this for now.

- jana

On Thu, Feb 9, 2017 at 11:57 AM, Ian Swett <[email-masked]> wrote:

> 1) This implicitly requires the connection ID to always be stated, which
> as Ryan said, inflates the packet header substantially from the status quo
> of what we send server to client, which I'm not a fan of from a practical

---

From: Eric Rescorla <[email-masked]>
Date: Thu, 9 Feb 2017 13:38:30 -0800

First, Martin, thanks for doing the work I promised to do. I've got some
more things I'm going to try that with :)

> (i) it attempts to compress the header, in some cases

I thought there was agreement that making the header smaller was good. Not
sure how we would have consensus for that in the abstract, so we probably
just need to debate whether or not this particular form of compression is
good.

> consensus (connection ID, magic field)

Hmm.... I thought we did have consensus for the magic field in the interim.
Of course that needs confirmation on the mailing list, but this seems like
a good venue for that.
I don't think we need concern ourselves with the connection ID, because
this proposal neatly accommodates removing the connection ID field, either
by having the server
tell the client it can (with no indicator) or if we like, stealing a bit
from the packet number to say ("here is a conn id"). There doesn't seem to
be a percentage in removing conn id from the special packets, so we don't
need to address that.

I think I do agree with you here, ultimately, but I'd like to leave it in
for now. My reasoning here is that you often find that you have a bunch of
small things that you want some flexibility for but that aren't enough to
add a whole new extension point, so you just get death of a thousand cuts
as you try to work around them. Contrariwise, if we have this extension
point available, we can see if it gets used and pull it out before pubreq.

> I propose parking this for now.

I'd rather we hash out these issues and decide on this PR or some revision
one way or the other. There's a lot of other stuff that's kind of piled up
behind the packet header.

-Ekr

>> detection bit(#279 <https://github.com/quicwg/base-drafts/issues/279>)
>> on every packet.  I think it makes sense to resolve these before
>> redesigning the packet header, since I believe it would substantially
>> change your current design?
>>> On Wed, Feb 8, 2017 at 8:42 PM, Martin Thomson <[email-masked]
>>> > wrote:
>>>

---

From: Jana Iyengar <[email-masked]>
Date: Thu, 9 Feb 2017 17:07:55 -0800

Hi Eric,

Responses inline.

> just need to debate whether or not this particular form of compression is

Agreed in principle, but as Ryan points out, this makes the connection ID
show up all the time, which increases header size.

> Hmm.... I thought we did have consensus for the magic field in the
> interim. Of course that needs confirmation on the mailing list, but this
> seems like a good venue for that.

Yes, you're right. We did have consensus on encoding version neg packets to
include a ver + magic for directionality, but as you note, this hasn't been
confirmed on the list, and we should do that. This is a simple change that
addresses the DoS issue by adding directionality (Issue #135
<https://github.com/quicwg/base-drafts/issues/135>), and that change would
be relatively small.

> point available, we can see if it gets used and pull it out before pubreq.

I am sympathetic to your point about death by a thousand cuts, but I don't
think we're there yet. I'm still of the opinion that this introduces
unwarranted arbitrary extensibility in the header, since I don't see the
warranting use cases.

> behind the packet header

In that case, I'd suggest that we separate the version + magic flag in one
PR to address the DoS issue. As discussed at the interim
<https://github.com/quicwg/wg-materials/blob/master/interim-17-01/minutes-24.md#issue-135--dos-using-version-negotiation-packets>,
this would simply mean that we have an interpretation of the version bit
that includes the magic part.

For the long header (inlining my comments below:)
* Octet 0: Special
  * Bit 7 (i.e., 0x80): SHORT_HEADER (set to 0 here)
  * Bit 6-5: Type
    * 11 - client packet
    * 10 - server packet
    * 01 - public reset
    * 00 - version negotiation

Why do you need two codepoints for regular packets? The magic header gives
directionality on initial packets, and the connection keys on subsequent
rounds, right? You need only three codepoints in all here.

Why do we need these?

    * other values mean that the payload following the packet number
contains
     an IPv6-style extension header

Why do we need this?

* Octets 1-3: Magic (this can be short given that we will have a MAC as
well)
  * 0x756963 for a client,
  * 0x554943 for a server

SGTM, based on consensus.

The proposed short header removes the following bits that I would not want
to lose:
- packet number size. The packet number size currently changes as our
estimation of how many packets fit in the cwnd changes (loosely speaking)
and is dynamic through the connection.
- Connection ID flag, and makes the Connection ID required in all packets.
As previously pointed out, this flexibility is quite useful and reduces
header size quite a bit in the direction where it commonly matters most
(server->client), but it can be used by any endpoint as long as it does not
need Connection ID for routing on incoming packets.

Based on my take on the long and short headers above:

If we remove the extensibility points, eliminate server/client
directionality in the header bits, and retain the fields I noted above, I'm
not sure that there's much to be had by separating the long and short
headers. The resulting header looks as follows on all packets:
- TT: Packet type
    * 00 - version negotiation packet
    * 01 - public reset
    * 1X - regular packet
- Key Phase
- Connection ID
- Packet Number Size (2 bits)

The only difference from the spec is the TT bits, which is equivalent to
the explicit V and PR bits in the spec right now, since with V and PR bits:
10 - version negotiation packet
01 - public reset packet (we could make this X1, to make it cover the
unused codepoint.)
00 - regular packet

I would suggest a PR that only adds a magic field for directionality, and
leaves the rest of it out; perhaps in a separate issue + PR to discuss why
these may be useful.
- jana

-Ekr
>>>> On Wed, Feb 8, 2017 at 8:42 PM, Martin Thomson <
>>>> [email-masked]> wrote:
>>>>
>>>> ​In currently deployed QUIC, 1-RTT packets from the server to the
>>>> client do not have connection ID present. (This is because an endpoint
>>>> tells the peer how many connection​ ID bits it needs the peer to send. In
>>>> the case of clients, since they only have 1 connection on a given socket,
>>>> the connection ID is not needed.). These packets also typically have a 1 or
>>>> 2 byte packet number. So the header ends up being:  1 byte public flags + 1

---

From: Martin Thomson <[email-masked]>
Date: Fri, 10 Feb 2017 13:40:19 +1100

Hi Jana,

To address your concerns:

Connection ID removal:
I believe that ekr addressed your concern about the connection ID
removal, so I'm surprised that you bring it up again.  Since we
haven't really discussed it thus far, I don't know how important this
feature is.  I believe that it means making a choice about whether you
think connection migration is important or not.  Whether it requires
an explicit per-packet signal is debatable; in developing the
proposal, my assumption was that negotiating connection ID away would
be good enough.

Packet number size:
There's a trade-off here.  One of the features of my proposal is that
the connection ID remains in the same place for both short- and
long-form.  I agree that 30 bits is far more than we need, but the
bits were just sitting there doing nothing otherwise.

Also, I don't feel much urgency behind byte-level optimizations for
small BDP when they come at the expense of other things.  The trends
are all toward increases in that number.

Extensibility:
ekr explained the rationale here, it's an escape valve.  I too would
dearly like to remove the feature.  Given that I can't think of a use
case, I hope that time will come soon.

It seems like your counter-proposal just reiterates the current design
with some minor adjustments.  I just don't think that is sufficient to
address the concerns that people have raised about the excessive
number of variations in packet layout.  Adding a magic field in the
way you propose only compounds that problem.

The reason for needing a proposal was that it was clear that we needed
a holistic approach to designing the header.  There were just too many
different, interacting issues.  My proposal addresses many of those at
once with a simple change.  From a skim through the list: #40, #56,
#67, #119, #133, #135, #170, #185, #193, and #244 all go away.  It
also goes some way to address #147 and #205.

On 10 February 2017 at 12:07, Jana Iyengar <[email-masked]> wrote:
>>> transport draft talked about Regular and Special packets, which may be worth
>>> reconsidering.) That said, I think this proposal conflates three things:
> addresses the DoS issue by adding directionality (Issue #135), and that
> change would be relatively small.
>
>> add a whole new extension point, so you just get death of a thousand cuts as
>> you try to work around them. Contrariwise, if we have this extension point
>> available, we can see if it gets used and pull it out before pubreq.
>
>
> PR to address the DoS issue. As discussed at the interim, this would simply
> mean that we have an interpretation of the version bit that includes the
> magic part.
>
>
> The only difference from the spec is the TT bits, which is equivalent to the
> explicit V and PR bits in the spec right now, since with V and PR bits:
> 01 - public reset packet (we could make this X1, to make it cover the unused
> codepoint.)
> 00 - regular packet
>
>
>>>> 2) I believe we may want to add packet number echo bit(#269) and
>>>> possibly a loss detection bit(#279) on every packet.  I think it makes sense
>>>> to resolve these before redesigning the packet header, since I believe it
>>>> would substantially change your current design?
>>>>> On Wed, Feb 8, 2017 at 8:42 PM, Martin Thomson
>>>>> <[email-masked]> wrote:
>>>>>>
>>>>> In currently deployed QUIC, 1-RTT packets from the server to the client
>>>>> peer how many connection ID bits it needs the peer to send. In the case of
>>>>> clients, since they only have 1 connection on a given socket, the connection
>>>>> ID is not needed.). These packets also typically have a 1 or 2 byte packet
>>>>> number. So the header ends up being:  1 byte public flags + 1 or 2 byte
>>>>> packet number for a total of 2-3 bytes. This new format seems to be much
>>>>> larger.
>>>>>
>>>>>>
>>>>>> below.
>>>>> contains a version that the server does not support, it may well be the case
>>>>> that the packet number layout may be different in the new version. So I'm
>>>>> Public reset packets are commonly sent when a server receives a packet

---

From: Jana Iyengar <[email-masked]>
Date: Thu, 9 Feb 2017 22:09:39 -0800

Martin,

Responses inline.

> proposal, my assumption was that negotiating connection ID away would

Apologies -- yes, you're right that ekr addressed it. I agree that it's
reasonable to not have it in each packet. I would suggest that changing the
packet header to not have it should be accompanied by text to negotiate it
during handshake.

On its value: I would strongly argue against its removal -- it is what
allows QUIC to survive NAT rebinding, which we know happens often enough to
matter. Removing it would be a fundamental change to the protocol, and
would cause measurable performance impact.

> bits were just sitting there doing nothing otherwise.

I don't follow -- the 30 bits would be used by the payload, right?

> are all toward increases in that number.

I think exactly the opposite: you gain two bits by removing the packet
number size bits and you lose 1-few bytes per packet. That's additional
overhead in each packet. While we should try to optimize for low bandwdith
as long as it is reasonable,  I'll note that my argument isn't based on
optimizing for low-bandwidth networks; I just don't see the tradeoff here.
What do you gain by removing packet number size bits (besides 2 bits in the
header)?

> case, I hope that time will come soon.

I don't think we should add extensibility options now that we hope to never
use. If we don't think we'll need it, let's not include it. Including it
attracts nuisance, since extensible fields often find reasons to be
extended. I don't agree with the rationale: providing an escape valve
suggests that we may need to add something that we won't have a place to
put so we can throw it into extensions. If we need something in the header
later that's important enough, we can always redo this header later.

> way you propose only compounds that problem.

I wasn't making a counter proposal -- I was walking down the path of
figuring out what I wanted to retain in the header, and if we had those
bits, how different the header would look from what it is now. What I wrote
down was what I realized as I walked down that path.

One clarification question you haven't answered: Why do you need a
client/server bit in Typ?

> also goes some way to address #147 and #205.

(It's late now for me -- I'll go through the issues you've listed tomorrow
and respond to this point.)

- jana

On 10 February 2017 at 12:07, Jana Iyengar <[email-masked]> wrote:
> worth
> the
> unused
> >>>>>> There are two forms of QUIC common header: long and short.  Long
> form
> >>>>>> packets
> >>>>>> are used for the initial exchange - until both 1-RTT packet
> protection
> >>>>>> can be
> >>>>>> started AND version negotiation is complete.  Short form packets
> carry
> >>>>>> the
> >>>>>> bulk of the data.
> >>>>>>
> >>>>>> identifies the role of the sender in the first octet and it
> identifies
> >>>>>> the
> >>>>>> packet as a QUIC packet.
> >>>>>>
> >>>>>> The cost is that it makes occasional packets a little larger (the
> long
> >>>>>> header
> >>>>>> handshake packets).  This is an acceptable trade-off given that
> only a
> >>>>>> few of
> connection
> >>>>>> * Octets 16-19: packet number (low 4 octets, starts at a random
> 32-bit
> >>>>>> value)
> >>>>>> * Octets 20+: payload
> >>>>>>
> >>>>>> values.  They would have no semantic value, though they might serve
> to
> >>>>>> provide
> >>>>>> These long-form packets are used for anything that doesn't have
> 1-RTT
> >>>>>> packet
> >>>>>> 5/7-bit code for protected long-form packets, but that's easy to do
> if
> >>>>>> we need
> >>>>>> 0x00 is reserved for a null extension header, allowing the full
> space
> >>>>>> to be
> >>>>>> we define a 5- or 7-bit code for "small bit of handshake, followed
> by
> >>>>>> more",
> >>>>>> The remainder of the first four octets contain the packet number.
> 30
> >>>>>> bits
> >>>>>> should be plenty.  If a need is found for more flags, those can
> steal
> >>>>>> upper

---

From: Martin Thomson <[email-masked]>
Date: Fri, 10 Feb 2017 17:37:59 +1100

Brief answers, we'll resume when you have operating capacity.

> What do you gain by removing packet number size bits (besides 2 bits in the

Consistent position of the connection ID primarily.

And I didn't really propose removing the bits, it's just that if you
accept that having a stable position for the routing information is
valuable, there is no point in flexibility above 30 and going below 30
means you have idle bits lying around.  So it just happened.

> client/server bit in Typ?

It's not really a bit - obviously the part where I talk about 5 and 7
bits was a little obtuse and I should on improving my explanation of
that some.  The reason was largely so that it wouldn't say "Quic" and
"QUIC", but could say "quic" and "QUIC".  An inane reason, I know, but
the actual space available is so large that a conceit like that seemed
affordable.

I'm now of the opinion that you can use that first byte (after the
"special" bit) as a single unified type (of 7-bits) and dispense with
the bit twiddling.  But I didn't come to that conclusion until well
after I had written this up and I thought that the formulation with a
2-bit type might end up being easier for people to understand.

---

From: Ian Swett <[email-masked]>
Date: Sun, 12 Feb 2017 12:58:59 -0500

> case, I hope that time will come soon.
All the use cases I can think of for extensibility would be on short
packets, so if we're going to do this, I think it should be available there
as well.  Also, the last time I remember talking about an extensible UDP
header, it was at the PLUS BoF, where there were quite a few objections,
notably on privacy grounds.

I don't understand ekr's rationale.  We'll already be doing negotiation as
part of the QUIC handshake in TLS, so I feel like that combined with
version negotiation provide a pretty substantial escape valve.  These
extensions seem only valuable to communicate to or from middleboxes or if
we absolutely have to add something to 0RTT packets.

> also goes some way to address #147 and #205.
After reading through them, I don't believe #40, #56, #67, #119, #133,
#135, #170, #185, #193, and #244 all go away with this proposal, since this
proposal really is about framing. Some were tentatively resolved at the
interim or are in the process of being resolved by proper
documentation(thanks for your #67 PR, BTW).  Additionally, this has
implications on other issues, such as #203, #269 and #279, and I opened
#292 and #293 to discuss whether a fixed location for connection id and 4
byte alignment are requirements.

On the other hand, if we had clear direction on most of the non-editorial
issues listed(except #40, which is really only a question of framing), we'd
be in a better position to fix up the framing with a clear set of goals.

---

From: Jana Iyengar <[email-masked]>
Date: Sun, 12 Feb 2017 11:19:11 -0800

Responding to Ian and Martin together. A couple of high-order points:
(i) There may be value in the separation of long and short headers, and I'd
like to keep that general idea around, and come back to this later. That
said, as Ian points out, there are things that aren't resolved yet, and
redoing the header at this time seems like an early optimization. I think
we should address the things that we have consensus for (adding a magic
header for directionality). We had consensus on attempting to simplify the
headers, which we can do, but I'd be wary of doing it at a cost to common
use cases.
(ii) Let's not add arbitrary extensibility to the header. We have
versioning, we have transport params, and now this adds a third
extensibility option which seems unnecessary.

> we absolutely have to add something to 0RTT packets.

I agree. If we have a need for more header fields, let's revisit the header
itself. Providing arbitrary extensibility hoping that it doesn't get used
is a bad strategy.

>> way you propose only compounds that problem.
I would like to come back to this point -- yes there were some concerns
raised about the variations in packet layout. I don't think there's been a
convincing case that this is a major issue for implementations. Where
exactly is this variability in headers a problem? I'd like to hear more
about this issue before we embark on a complete redesign. Specifically,
implementation experience (ours at least, others with experience should
chime in) suggests that this has not been a concern for implementation at
least.

> be in a better position to fix up the framing with a clear set of goals.

I spent time going through all the issues as well. These issues are either
addressed by using the magic field for directionality, by using
server-generated connection ID, or by editorial work, all of which are
independent of the framing changes. These changes can be made simply in the
current format. The newer issues should be addressed, and we can always
come back to this framing change later, if it's still warranted.

- jana

>> >>>>>> This removes a lot of the flexibility that was the source of most
>> of
>> >>>>>> the
>> >>>>>> * Octets 1-3: Magic (this can be short given that we will have a
>> MAC
>> >>>>>> as well)
>> >>>>>>   * 0x756963 for a client,
>> >>>>>>   * 0x554943 for a server
>> >>>>>>
>> >>>>>> values.  They would have no semantic value, though they might
>> serve to
>> >>>>>> provide
>> >>>>>> protection and prior to the completion of version negotiation.
>> Once
>> >>>>>> both
>> >>>>>> conditions are met, switch to sending short-form packets.  I
>> haven't
>> >>>>>> defined any
>> >>>>>> 5/7-bit code for protected long-form packets, but that's easy to
>> do if
>> >>>>>> we need
>> >>>>>> this is based on to be successful.  Either way, this should at
>> least
>> >>>>>> have plenty
>> >>>>>> of hardware support.
>> >>>>>>
>> >>>>>> FWIW, I'm not sure that we need the complexity that this adds.
>> It's
>> >>>>>> not clear
>> >>>>>> That said, this form could be used to pack a TLS Finished into
>> 1-RTT
>> >>>>>> packets if
>> >>>>>> A short packet header - in this version - reserves two bits from
>> the
>> >>>>>> first
>> >>>>>> octet:
>> >>>>>> bits from the packet number.  (Frankly, I suspect that 14 bits
>> might
>> >>>>>> be

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Feb 2017 11:35:42 +1100

> notably on privacy grounds.

The principle here is that short headers don't need extensibility in
the same way.  While we might want to be careful about what can change
in the short header, in theory it is possible to change everything
about the short header by negotiation.  And you said as much yourself.

> I don't understand ekr's rationale.

Is that a rhetorical device?

FWIW, I entirely agree in that I don't *think* that we need
extensibility.  But I'd rather delete something when I'm certain it's
not needed than find we're building adhoc systems.

Since that's a nonessential part of the proposal, I'm happy to remove
it on the understanding that the escape valve exists.

> After reading through them, I don't believe #40, #56, #67, #119, #133, #135,
> #170, #185, #193, and #244 all go away with this proposal,

I suggest we don't belabor this point.  We clearly disagree (at least
on the ones I checked).

---

From: Martin Thomson <[email-masked]>
Date: Mon, 13 Feb 2017 11:39:05 +1100

On 13 February 2017 at 06:19, Jana Iyengar <[email-masked]> wrote:
> There may be value in the separation of long and short headers, and I'd like
> to keep that general idea around, and come back to this later. That said, as
> Ian points out, there are things that aren't resolved yet, and redoing the
> header at this time seems like an early optimization.

Shelving the discussion isn't going to work.  We've a lot of
outstanding work that is affected by this (as you and Ian readily
acknowledge) and uncertainty on this point is affecting our ability to
make progress.

It's hardly optimization, the structure of the bits in the handshake
is foundational.