Subject: [QUIC] Comments on draft-hamilton-quic-transport

From: Eric Rescorla <[email-masked]>
Date: Tue, 15 Nov 2016 07:05:12 +0900

Sorry about the late review. I just got around to writing up my comments.

SUSTANTIVE
You make a lot of attempts to shave a byte off here or there by variable
length encodings. I'm not sure this isn't more trouble than it's worth.

S 3.4.
   QUIC acknowledgments also explicitly encode the delay
   between the receipt of a packet and its acknowledgment being sent,

This seems like it might make offload boxes harder to build.

S 3.7.
I'm not sure I'm convinced by this story about the conn-id and
NAT rebinding. The issue is that the lifetime of the incoming
NAT pinhole and the NAT address binding are basically the same.

To take HTTP as a use case, as I understand it there are three common
traffic patterns.

- The client is making requests and getting responses
- The client has made a bunch of requests and is downloading
  a big pile of data.
- The client is just waiting for a server to send something
  (long poll, websockets) for things like incoming VoIP calls.

In the first two cases, the NAT won't rebind because there is traffic
flowing. In the third the connection is idle, so the NAT rebinds, but
the server speaks first (to send the message), so the conn-id doesn't
help. In order to keep the NAT pinhole alive, the client needs to send
keepalives, but then the NAT doesn't rebind the conn-id isn't needed
for the server to match the new connection because the binding
persists.

I think there are probably edge cases where the client does keepalives
but is wrong about the binding lifetime and this helps, but those just
seem like edge cases. Given that the conn-id has privacy implications
this seems like it needs serious consideration.

This is just a placeholder that I, like others, think we need to
revisit conn-id.

S 4.1.
I know we're considering changing conn id but if you're going to say
"random", I believe "cryptographically random" is the requirement

S 4.4.
This section is pretty incomplete: what is the threat model that
public reset is supposed to fit into? How is RNON computed?  What's a
"tag-value map"? It's never defined. Are you still using this?

S 5.2.
This version negotiation scheme seems fine in itself, but I think
you also need to specify some kind of options handshake. Experience
tends to show that just revving the version number every time you
want to change features doesn't work well.

   When the client receives a Version Negotiation packet from the
   server, it should select an acceptable protocol version.  If such a
   version is found, the client MUST resend all packets using the new
   version, and the resent packets MUST use new packet numbers.  These
   packets MUST continue to have the VERSION flag set and MUST include
   the new negotiated protocol version.

This text isn't going to work. Say, for instance that QUIC version
n+1 has a totally different HTTP binding, you would need to send
new packets. The idea here, I think, is 'this is a re-start' but
the semantics of that are a lot more complicated than that's here.

S 5.2.1.1.

    QUIC encodes the transport parameters and options as tag-value pairs,
    all as 7-bit ASCII strings.  QUIC parameter tags are listed below.

As noted, you don't define this, and it doesn't in fact seem like the
values here are 7-bit ASCII strings.

I believe that certificate compression is a good idea, and TLS has
a weaker version of this (cached-info). However, I also know that the
version in fielded QUIC is pretty Google-specific so I think this
SHOULD needs to be more of a "should consider" until we demonstrate that
a good general version is possible.

S 6.1.
It's sorta gross to have a FIN bit which is wased on every packet
but only used very occasionally (at the end of the stream).
I wonder if it would be better to just require that once FIN has been
sent on a stream, any mention of that stream in a packet also come
with some sort of FIN-frame. Then you don't have any per-packet overhead
during the lifetime of the stream. If designed properly, it would
also have the property that you could *pre-advertise* FIN like
HTTP content length.

S 6.2.
This document really should include guidance about how to generate ACKs
well, not just point that to loss recovery.

I'm unpersuaded by this ACK-skipping defense. It seems like it's going
to chew up ACK bandwidth for not too much value, and so senders won't
do it. I would instead suggest that the ACK block just include a signature
of all the packets being ACKed (which both sides need to know anyway).
This can be something fast and order-dependent like XOR and then
the receiver of the ACK can validate it and terminate the entire connection
if it detects shenanigans.

S 6.5.
Please give some guidance on "BLOCKED" as written, it seems like if stream
X is blocked but the app is still writing to send BLOCKED frames up to the
overall connection window. That's not what we want, right?

S 6.7.
Rather than have a padding frame, I would suggest adopting a TLS 1.3-style
padding scheme at the encryption layer.

S 9.1.1.
   To avoid this de-synchronization, a RST_STREAM sender MUST include
   the final byte offset sent on the stream in the RST_STREAM frame.  On
   receiving a RST_STREAM frame, a receiver definitively knows how many
   bytes were sent on that stream before the RST_STREAM frame, and the
   receiver MUST use the final offset to account for all bytes sent on
   the stream in its connection level flow controller.

I find this text hard to read wrt to which direction. Is this about
the last byte sent by the RST_STREAM sender or the last byte received
by the sender before he sent the RST_STREAM.

EDITORIAL
There are a lot of places in this document where I had questions
that were answered later. Some restructuring might help. At the risk
of self-citing, I would suggest an RFC4101-style overview at the beginning.
If the editors are willing to accept a PR, I would be willing to provide
this.

Please do whatever you need to do to make section numbers work. It's
a pain to read a document where every xref is "Section XXX".

S 3.7.
you never define "rebound client".

S 6.2.
I get the rationale for this backward-delta scheme, but as written
it's pretty hard to understand. I know this is kind of a vague
comment; once this is up on Github, I will attempt to provide some
text.

S 6.4.
Please say here that you can't retract window advertisements, not just
later.

S  7.
      All application data sent in STREAM frames MUST be retransmitted,
      with one exception.  When an endpoint sends a RST_STREAM frame,
      data outstanding on that stream SHOULD NOT be retransmitted, since
      subsequent data on this stream is expected to not be delivered by
      the receiver.

This applies to both directions, right. I.e., "when an endpoint has sent
or received an RST_STREAM frame"

S 8.
This is an example of text that would improve the document by being
earlier so people have the overview.

S 9.
      receiver advertises the maximum absolute byte offset in the stream or

"absolute byte offset" is weird. Maybe "abolute byte position"?

---

From: Mike Bishop <[email-masked]>
Date: Mon, 14 Nov 2016 22:29:27 +0000

I agree about the privacy implications.  However, on our notification channel, we’ve had to implement logic to heuristically determine the lifetime of idle port mappings and time our keep-alives appropriate to the network.  The question here seems to be what happens when the client discovers that the port has been scavenged.  I don’t think it’s an edge case, but an expected one – at least until the client can determine the appropriate keep-alive frequency.

Perhaps we just mandate keep-alives often enough that we think this will never happen, but that also has power implications.

From: QUIC [mailto:[email-masked]] On Behalf Of Eric Rescorla
Sent: Tuesday, November 15, 2016 7:05 AM
To: [email-masked]
Subject: [QUIC] Comments on draft-hamilton-quic-transport

SUSTANTIVE

S 3.4.

S 3.7.

S 4.1.

S 4.4.

S 5.2.

S 5.2.1.1.

S 6.1.

S 6.2.

S 6.5.

S 6.7.

S 9.1.1.

EDITORIAL
There are a lot of places in this document where I had questions
that were answered later. Some restructuring might help. At the risk
of self-citing, I would suggest an RFC4101-style overview at the beginning.
If the editors are willing to accept a PR, I would be willing to provide this.

S 3.7.

S 6.2.

S 6.4.

S  7.

S 8.

S 9.

---

From: Eric Rescorla <[email-masked]>
Date: Tue, 15 Nov 2016 08:40:55 +0900

> if it detects shenanigans.

Replying to myself, this isn't going to work as I wrote it. Will ponder a
bit about
whether there's a way to do it that does.

-Ekr