Subject: [quicwg/base-drafts] Allow CONNECTION_CLOSE in 0-RTT (#3440)

From: Martin Thomson <[email-masked]>
Date: Thu, 06 Feb 2020 07:35:22 -0800

This allows us to avoid treating 0-RTT specially more generally.

The advice on where to send CONNECTION_CLOSE seems ornate, but it
reduces to &quot;send CONNECTION_CLOSE in every space you have keys for&quot;.

Closes #3435.
You can view, comment on, or merge this pull request online at:

  https://github.com/quicwg/base-drafts/pull/3440

-- Commit Summary --

  * Allow CONNECTION_CLOSE in 0-RTT

-- File Changes --

    M draft-ietf-quic-tls.md (5)
    M draft-ietf-quic-transport.md (45)

-- Patch Links --

https://github.com/quicwg/base-drafts/pull/3440.patch
https://github.com/quicwg/base-drafts/pull/3440.diff

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440

---

From: ianswett <[email-masked]>
Date: Thu, 06 Feb 2020 09:12:53 -0800

ianswett approved this pull request.

> -least one of them is processable by the client.  Similarly, a peer might be
-unable to read 1-RTT packets, so an endpoint SHOULD send CONNECTION_CLOSE in
-Handshake and 1-RTT packets prior to confirming the handshake.  These packets
-can be coalesced into a single UDP datagram; see {{packet-coalesce}}.
+* A client will always know whether the server has Handshake keys (see
+  {{discard-initial}}), but it is possible that a server does not know whether
+  the client has Handshake keys.  Under these circumstances, a server SHOULD
+  send a CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure
+  that at least one of them is processable by the client.
+
+* A client that sends CONNECTION_CLOSE in a 0-RTT packet cannot be assured of
+  the server has accepted 0-RTT and so sending a CONNECTION_CLOSE frame of type
+  0x1c in an Initial packet makes it more likely that the server can receive
+  the close signal, even if the application error code might not be received.
+
+* A peer might be unable to read 1-RTT packets, so an endpoint SHOULD send

Suggestion to reorder this sentence: "Prior to confirming the handshake, a peer might be unable to process 1-RTT packets, so an endpoint SHOULD send CONNECTION_CLOSE in Handshake and 1-RTT packets."

> +* A client will always know whether the server has Handshake keys (see
+  {{discard-initial}}), but it is possible that a server does not know whether
+  the client has Handshake keys.  Under these circumstances, a server SHOULD
+  send a CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure
+  that at least one of them is processable by the client.
+
+* A client that sends CONNECTION_CLOSE in a 0-RTT packet cannot be assured of
+  the server has accepted 0-RTT and so sending a CONNECTION_CLOSE frame of type
+  0x1c in an Initial packet makes it more likely that the server can receive
+  the close signal, even if the application error code might not be received.
+
+* A peer might be unable to read 1-RTT packets, so an endpoint SHOULD send
+  CONNECTION_CLOSE in Handshake and 1-RTT packets prior to confirming the
+  handshake.
+
+CONNECTION_CLOSE frames that are sent in multiple packets can be coalesced into

```suggestion
CONNECTION_CLOSE frames sent in multiple packets can be coalesced into
```

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#pullrequestreview-354623198

---

From: Martin Thomson <[email-masked]>
Date: Sun, 09 Feb 2020 13:53:36 -0800

@martinthomson pushed 1 commit.

68d9617e612166f9ea38fca9b11a7bbdd63e212d  Ian's suggestions

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/f4c094c778450378c8785d0d5bd40e562bf772c8..68d9617e612166f9ea38fca9b11a7bbdd63e212d

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 09 Feb 2020 19:06:37 -0800

kazuho commented on this pull request.

> @@ -328,8 +328,7 @@ encryption levels:
 
 - PADDING and PING frames MAY appear in packets of any encryption level.
 
-- CRYPTO frames and CONNECTION_CLOSE frames signaling errors at the QUIC layer
-  (type 0x1c) MAY appear in packets of any encryption level except 0-RTT.
+- CRYPTO frames MAY appear in packets of any encryption level except 0-RTT.
 
 - CONNECTION_CLOSE frames signaling application errors (type 0x1d) MUST only be
   sent in packets at the 1-RTT encryption level.

For consistency, should we strike this point to allow the use of application-level CONNECTION_CLOSE frames in 0-RTT? Looking at the changes proposed for the transport draft, I believe that that is the intent.

> @@ -328,8 +328,7 @@ encryption levels:
 
 - PADDING and PING frames MAY appear in packets of any encryption level.
 
-- CRYPTO frames and CONNECTION_CLOSE frames signaling errors at the QUIC layer
-  (type 0x1c) MAY appear in packets of any encryption level except 0-RTT.
+- CRYPTO frames MAY appear in packets of any encryption level except 0-RTT.

I am not sure if this change is correct, because this would mean that CONNECTION_CLOSE is allowed only in 0-RTT and 1-RTT levels.

I think what we need to do here is add CONNECTION_CLOSE (type 0x1c) to the point above that talks about PADDING and PING frames.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#pullrequestreview-355671063

---

From: Mike Bishop <[email-masked]>
Date: Wed, 12 Feb 2020 11:44:47 -0800

MikeBishop commented on this pull request.

This feels a little sticky:
- App-level CLOSE MUST only be sent in 0-RTT or 1-RTT
- If you're sending a CLOSE in 0-RTT, you OUGHT TO repeat it in an Initial packet, except that you can't if it's application-level.

Does that explicitly mean sending two different error codes at the two levels?

> -client has Handshake keys.  Under these circumstances, a server SHOULD send a
-CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure that at

In a handshake that requires multiple flights (HRR, client certs, etc.), the client might also have Handshake keys but not 1-RTT keys.  This isn't the common case, but I believe it's still permitted?

Also, why are the other two SHOULDs, while this is merely a statement about likely outcomes?

> @@ -5680,10 +5689,10 @@ Reason Phrase:
   This SHOULD be a UTF-8 encoded string {{!RFC3629}}.
 
 The application-specific variant of CONNECTION_CLOSE (type 0x1d) can only be
-sent using an 1-RTT packet ({{QUIC-TLS}}, Section 4).  When an application
-wishes to abandon a connection during the handshake, an endpoint can send a
-CONNECTION_CLOSE frame (type 0x1c) with an error code of 0x15a ("user_canceled"
-alert; see {{?TLS13}}) in an Initial or a Handshake packet.
+sent using 0-RTT or 1-RTT packets ({{QUIC-TLS}}, Section 4).  When an
+application wishes to abandon a connection during the handshake, an endpoint
+can send a CONNECTION_CLOSE frame (type 0x1c) with an error code of 0x15a
+("user_canceled" alert; see {{?TLS13}}) in an Initial or a Handshake packet.

This feels slightly at odds with the above advice to repeat the frame in both 0-RTT and Initial.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#pullrequestreview-357732001

---

From: Martin Thomson <[email-masked]>
Date: Thu, 13 Feb 2020 15:57:26 -0800

c8270f602717d0fc0bb3dec51085a7a3ab10665b  Define APPLICATION_ERROR code for CONNECTION_CLOSE

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/68d9617e612166f9ea38fca9b11a7bbdd63e212d..c8270f602717d0fc0bb3dec51085a7a3ab10665b

---

From: Martin Thomson <[email-masked]>
Date: Thu, 13 Feb 2020 16:01:24 -0800

I've updated this one to fix the other issue as well.  And yes @MikeBishop, that means multiple error codes.  That's a little ugly, but otherwise we have cases where CONNECTION_CLOSE is initiated by the application in a way that the peer can't consume it.  We either let the connection die without CONNECTION_CLOSE, do some mapping, or we leak application state into "cleartext".  I like the explicit signal.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#issuecomment-586031660

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 13 Feb 2020 18:10:17 -0800

So the proposed changes are the following two?
* allow CONNECTION_CLOSE in 0-RTT
* use APPLICATION_CLOSE instead of "user_cancelled"?

Assuming that is the case, changes to the transport draft looks good to me modulo the point below. I think my comments to the TLS draft still holds.

+  send a CONNECTION_CLOSE frame in both Handshake and Initial packets to ensure
+  that at least one of them is processable by the client.
+
+* A client that sends CONNECTION_CLOSE in a 0-RTT packet cannot be assured of
+  the server has accepted 0-RTT and so sending a CONNECTION_CLOSE frame in an
+  Initial packet makes it more likely that the server can receive the close
+  signal, even if the application error code might not be received.
+
+* Prior to confirming the handshake, a peer might be unable to process 1-RTT
+  packets, so an endpoint SHOULD send CONNECTION_CLOSE in both Handshake and
+  1-RTT packets.  A server SHOULD also send CONNECTION_CLOSE in an Initial
+  packet.
+
+An CONNECTION_CLOSE of type 0x1d MUST be replaced by a CONNECTION_CLOSE of type
+1c when sending the frame in Initial packets. Otherwise, information about the

Maybe change to "in Initial or Handshake packets"?

I think we need to call out Handshake packets too, because a client cannot tell if it is talking to a legitimate server when it sends a CONNECTION_CLOSE frame using a Handshake packet.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#pullrequestreview-358673839

---

From: Martin Thomson <[email-masked]>
Date: Thu, 13 Feb 2020 18:43:13 -0800

@martinthomson pushed 2 commits.

f01a8ee6672a99e47b4542d7b092a332bf95c7ee  Frame placement by packet number space
a7f2033d821e85766450dc3f75eb033458828b9c  Remove some more encryption level stuff

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/c8270f602717d0fc0bb3dec51085a7a3ab10665b..a7f2033d821e85766450dc3f75eb033458828b9c

---

From: Marten Seemann <[email-masked]>
Date: Sun, 16 Feb 2020 00:47:46 -0800

marten-seemann commented on this pull request.

Could we simplify these 3 points by just saying:
```An endpoint SHOULD send a CONNECTION_CLOSE in all encryption levels that it possesses keys for.```

+
+application state might be revealed. Endpoints SHOULD use the APPLICATION_ERROR
+code when performing this conversion.

What happens to the reason phrase? Can we mandate endpoints to clear it when using the APPLICATION_ERROR?

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#pullrequestreview-359388503

---

From: Mike Bishop <[email-masked]>
Date: Tue, 25 Feb 2020 12:04:12 -0800

MikeBishop approved this pull request.

Modulo clearing the reason phrase, this looks good.

-- 
You are receiving this because you are subscribed to this thread.
Reply to this email directly or view it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440#pullrequestreview-364410986

---

From: Martin Thomson <[email-masked]>
Date: Wed, 26 Feb 2020 11:03:13 -0800

032b88e613631aa31d1d9f3e1ab58ce722cc876a  Reason phrase needs to be cleared

-- 
You are receiving this because you are subscribed to this thread.
View it on GitHub:
https://github.com/quicwg/base-drafts/pull/3440/files/a7f2033d821e85766450dc3f75eb033458828b9c..032b88e613631aa31d1d9f3e1ab58ce722cc876a