Subject: [quicwg/base-drafts] unrecoverable loss pattern leads to deadlock (#2863)

From: Marten Seemann <[email-masked]>
Date: Sat, 29 Jun 2019 22:14:23 -0700

There's a loss pattern that QUIC cannot recover from:
Assume client and server perform a handshake up to the point just after the server received the ClientFinished message. No packet loss happens so far. Both peers have now **completed** (but not yet **confirmed**) the handshake.

Right after sending the ClientFinished, the client sends a 1-RTT packet (e.g. containing application data). This packet is lost. The server sends an acknowledgement for the ClientFinished (in a Handshake packet), and this packet is lost as well. Furthermore, the server also sends a 1-RTT packet (e.g. containing a session ticket). This packet is successfully received and acknowledged by the client.

At this point the endpoint are in the following state: Since it received an acknowledgement for a packet sent with 1-RTT keys, the server now **confirmed** the handshake, and drops the Handshake keys. On the other hand, the client is still waiting for an acknowledgement for the ClientFinished, and retransmits it. It will however never receive an acknowledgement, since the server dropped the keys already.

-- 
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/issues/2863

---

From: Nick Banks <[email-masked]>
Date: Sun, 30 Jun 2019 07:33:23 -0700

Sounds like receiving a 1-RTT packet on the client side might need to be another way to confirm the handshake.
________________________________
From: Marten Seemann <[email-masked]>
Sent: Sunday, June 30, 2019 12:14:22 AM
To: quicwg/base-drafts
Cc: Subscribed
Subject: [quicwg/base-drafts] unrecoverable loss pattern leads to deadlock (#2863)

There's a loss pattern that QUIC cannot recover from:
Assume client and server perform a handshake up to the point just after the server received the ClientFinished message. No packet loss happens so far. Both peers have now completed (but not yet confirmed) the handshake.

At this point the endpoint are in the following state: Since it received an acknowledgement for a packet sent with 1-RTT keys, the server now confirmed the handshake, and drops the Handshake keys. On the other hand, the client is still waiting for an acknowledgement for the ClientFinished, and retransmits it. It will however never receive an acknowledgement, since the server dropped the keys already.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fquicwg%2Fbase-drafts%2Fissues%2F2863%3Femail_source%3Dnotifications%26email_token%3DAE5U2BKJ5EZBLQM2MERB6GDP5A6K5A5CNFSM4H4LZFRKYY3PNVWWK3TUL52HS4DFUVEXG43VMWVGG33NNVSW45C7NFSM4G4PF4FQ&data=02%7C01%7Cnibanks%40microsoft.com%7C4fd9053c4f2d4701c4a908d6fd19d0d8%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636974684655932091&sdata=JRTX%2BF4zbnsara0XzyE3FdB6gjPCXhoFA27oz%2FckEiY%3D&reserved=0>, or mute the thread<https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAE5U2BIOSYQ43BY5PIJUGXTP5A6K5ANCNFSM4H4LZFRA&data=02%7C01%7Cnibanks%40microsoft.com%7C4fd9053c4f2d4701c4a908d6fd19d0d8%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C636974684655942081&sdata=ZcvfuYM3iCAEt2nSyc7y4Y1SLix0n8AeLrJwyedW2KY%3D&reserved=0>.

-- 
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/issues/2863#issuecomment-507041222

---

From: Martin Thomson <[email-masked]>
Date: Sun, 30 Jun 2019 17:03:38 -0700

A server can send a 1-RTT packet before even completing the handshake, so a client receiving one doesn't mean anything.

In this scenario, the client will continue retransmitting the last cryptographic handshake flight.  That sounds terrible.  But if it ever has cause to send 1-RTT data (as it does in Marten's example, which I'm not sure is relevant), then it will retransmit that data on PTO.  When that is eventually acknowledged, that will confirm the handshake.

The more troublesome scenario is where the client sends nothing, only acknowledgments.  In that case the client will have a complete handshake that cannot be confirmed.

Would it be enough to say that "unless an endpoint sends some ack-eliciting data in 1-RTT packets, the handshake might remain unconfirmed indefinitely" and leave it at that?

-- 
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/issues/2863#issuecomment-507078367

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 30 Jun 2019 17:18:07 -0700

@martinthomson 
> In this scenario, the client will continue retransmitting the last cryptographic handshake flight. That sounds terrible. But if it ever has cause to send 1-RTT data (as it does in Marten's example,…

Agreed. IIRC, the assumption in the design team was that the client would have something to send.

> Would it be enough to say that "unless an endpoint sends some ack-eliciting data in 1-RTT packets, the handshake might remain unconfirmed indefinitely" and leave it at that?

+1. We may hint that "a client MAY send a PING packet to confirm the handshake."

-- 
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/issues/2863#issuecomment-507079412

---

From: Marten Seemann <[email-masked]>
Date: Sun, 30 Jun 2019 17:29:31 -0700

>  But if it ever has cause to send 1-RTT data (as it does in Marten's example, which I'm not sure is relevant), then it will retransmit that data on PTO.

@martinthomson Unfortunately, that wouldn't work. As long as the client has outstanding crypto data, it will only retransmit the crypto packets, see https://quicwg.org/base-drafts/draft-ietf-quic-recovery.html#rfc.appendix.A.9.

> +1. We may hint that "a client MAY send a PING packet to confirm the handshake."

@kazuho Agreed, although I'd prefer a SHOULD here.

-- 
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/issues/2863#issuecomment-507080436

---

From: Kazuho Oku <[email-masked]>
Date: Sun, 30 Jun 2019 18:19:32 -0700

FWIW, what I had in mind was something like "once the handshake is complete, endpoints SHOULD send ack-eliciting packets to confirm the handshake. If there is no application data to be sent, such packets can contain 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/issues/2863#issuecomment-507085110

---

From: MikkelFJ <[email-masked]>
Date: Sun, 30 Jun 2019 21:22:14 -0700

> Would it be enough to say that "unless an endpoint sends some ack-eliciting data in 1-RTT packets, the handshake might remain unconfirmed indefinitely" and leave it at that?

No i think the state needs to progress. Resources might be tied up and timeouts might be in place to weed out bad handshakes before a longer or indefinite idle timeout.

I would say the client MUST send at least one ack-eliciting 1-RTT packet once it is able to do so, and within, say, 1 PTO.

-- 
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/issues/2863#issuecomment-507110454