Subject: [quicwg/base-drafts] Discarding Initial context too soon leads to deadlock (#3395)

From: Christian Huitema <[email-masked]>
Date: Fri, 24 Jan 2020 11:56:52 -0800

Transport draft-25 says:
```
17.2.2.1.  Abandoning Initial Packets

   A client stops both sending and processing Initial packets when it
   sends its first Handshake packet.
```
That behavior can lead to a deadlock in the following scenario:

1) Client sends Initial
2) Server replies with coalesced packet, Initial+Handshake
3) Client replies with coalesced Initial ACK + Handshake ACK and waits for next server packet
4) Client's packet is lost
5) Server implements anti-amplification attack, waits for full size client packet before sending anything

I suggest changing the text to: _A client stops both sending and processing Initial packets when it
   sends its first **ack-eliciting** 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/issues/3395

---

From: ianswett <[email-masked]>
Date: Fri, 24 Jan 2020 14:19:54 -0800

In that case, the recovery draft says:
"Since the server could be blocked until more packets are received from the client, it is the client's responsibility to send packets to unblock the server until it is certain that the server has finished its address validation (see Section 8 of {{QUIC-TRANSPORT}}). That is, the client MUST set the probe timer if the client has not received an acknowledgement for one of its Handshake or 1-RTT packets."

So in this case, the client should keep sending Handshake packets and if one is received, it'll unblock the server.

There's also the alternate solution to the amplification/deadlock issue I documented in #3161 and #3162

-- 
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/3395#issuecomment-578324729

---

From: Christian Huitema <[email-masked]>
Date: Fri, 24 Jan 2020 18:16:00 -0800

My server has a somewhat radical approach to anti-amplification: it just does not retransmit anything before the client address is validated. That's a good way to find edge cases, such as getting the first packet from the server and missing all the other packets, which would logically elicit acks of their own. That also means that bundling a ping with a server packet is not appropriate.

Regarding the recovery text: yes, if the client keeps repeating the ACK-only handshake packet, that will break the deadlock. But then, few stacks will naturally repeat ACK-only packets and few server stacks will acknowledge them, which was my point about adding "ACK-eliciting". In my case, the deadlock is broken when client will eventually repeat the Initial packet, and that will work. But it would not if I deleted the Initial context.

So I do think we need a bit of a warning in this section. Either my suggestion about ack-eliciting, or if you prefer a pointer to the relevant section in the recovery draft.

At a minimum, I would like to see a small warning in the text 

-- 
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/3395#issuecomment-578367135

---

From: ianswett <[email-masked]>
Date: Sat, 25 Jan 2020 10:23:53 -0800

Section 8.1 of transport contains text that agrees with recovery:
"Packet loss, in particular loss of a Handshake packet from the
   server, can cause a situation in which the server cannot send when
   the client has no data to send and the anti-amplification limit is
   reached.  In order to avoid this causing a handshake deadlock,
   clients SHOULD send a packet upon a probe timeout, as described in
   [QUIC-RECOVERY].  If the client has no data to retransmit and does
   not have Handshake keys, it SHOULD send an Initial packet in a UDP
   datagram of at least 1200 bytes.  If the client has Handshake keys,
   it SHOULD send a Handshake packet."

Possibly the SHOULDs in transport should be MUSTs?

The original issue was #1764.

At the NY interim, the conclusion to #1764 was that the only way to prevent a deadlock in the presence of a server that would stop sending due to an anti-amplification factor was to force the client to continue sending.  The existing recovery text proscribes that and this is one of the relatively few portions of the recovery text that uses a MUST instead of a SHOULD because otherwise you do get a deadlock.

I don't believe the ack-eliciting suggestion is always going to work unless it's also reliable, so I'd rather stick with the existing solution.  I think the cause of this problem is the amplification limits, and doesn't have to do with abandoning Initial packets, so a reference to recovery would be most appropriate in section 

-- 
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/3395#issuecomment-578429987

---

From: Christian Huitema <[email-masked]>
Date: Sat, 25 Jan 2020 11:18:51 -0800

I guess this is most;y an editorial issue. The implementer that just reads 17.2.2.1 could just make the bad decision of sending an ack-only handshake, dropping the Initial context, and not thinking any more about it. Adding a back pointer to 8.1. would warn this implementer about potential consequences.

-- 
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/3395#issuecomment-578434923