Subject: [quicwg/base-drafts] max_packet_size in 0-RTT (#3447)

From: Martin Thomson <[email-masked]>
Date: Mon, 10 Feb 2020 13:32:20 -0800

In #3434, we discussed remembering transport parameters.  The spec currently implicitly requires that `max_packet_size` be remembered.  However, it does not explicitly prohibit servers from accepting 0-RTT when it plans to reduce the value of this transport parameter.  That might lead to clients sending 0-RTT packets that are too big for the server.

I see two options:

1. Require that the server not accept 0-RTT if it plans to reduce this value.

2. Require that the client use the minimum value (1200) for 0-RTT.

-- 
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/3447

---

From: martinduke <[email-masked]>
Date: Mon, 10 Feb 2020 14:59:37 -0800

I will note that we already had this discussion in #2467 (and it was the two of us!)

What are the use cases where max_packet_size would change?
- the server interface has changed and can't accept these anymore -- I would think this was de facto going to result in not accepting 0RTT if the packets were too large. I'm not sure why we would reject 0RTT packets that happened to fall under the new limit, in this case.
- the max_packet_size is being set for some other reason -- perhaps to match an MTU on the other side of a proxy, to reduce copying. Again, as a proxy implementer I'd probably take the data but dictate that future packets be correctly sized.

Is there some other use case I'm not aware of?

-- 
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/3447#issuecomment-584399944

---

From: ianswett <[email-masked]>
Date: Mon, 10 Feb 2020 17:25:22 -0800

I do not like the idea of option 2.

I think 1 is likely ok, though if the server can process the 0-RTT packets, it's just sub-optimal performance-wise(as in @martinduke  second example) then it's a bit annoying to have to choose between not decreasing the MTU and rejecting 0-RTT.

-- 
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/3447#issuecomment-584439890

---

From: Lars Eggert <[email-masked]>
Date: Wed, 19 Feb 2020 01:52:16 -0800

I think we need to see more (supportive) discussion in order to justify taking this on.

-- 
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/3447#issuecomment-588131258

---

From: martinduke <[email-masked]>
Date: Wed, 19 Feb 2020 12:24:26 -0800

I would like someone to articulate what harm is done if the server were to accept 0-RTT when the max_packet_size has decreased.

-- 
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/3447#issuecomment-588431533

---

From: Kazuho Oku <[email-masked]>
Date: Wed, 19 Feb 2020 23:57:43 -0800

@martinduke 
> I would like someone to articulate what harm is done if the server were to accept 0-RTT when the max_packet_size has decreased.

Consider the case where the original value of max_packet_size was 9000, and client sending 0-RTT packets of 9000 bytes. If the server's max_packet_size goes down to 1280 and the server accepts 0-RTT, the client would consider the 0-RTT packets it has sent to be lost. I think that would halve CWND (to 5 MTU) and we'd exit slow start. This negative impact is likely to be greater than the benefit we'd get from 0-RTT.

That said, I am not sure if I like the framing of the discussion, or the current definition of `max_packet_size`.

I think we might be conflating the maximum size of QUIC packets and the maximum size of UDP datagrams, and I might argue that what matters in reality is the size of UDP datagrams.

As `max_packet_size` is a limit at the QUIC packet level, the transport draft allows a sender to send (and therefore requires a receiver to not discard) a UDP datagram that contains multiple QUIC packets being colesced, each of those QUIC packets being as large as `max_packet_size`. A server might send a UDP datagram that is 3x of `max_packet_size` (datagram consisting of full-sized Initial, Handshake, 1-RTT packet). Once a client receives the TP, it might send a UDP datagram that is 2x of `max_packet_size` (consisting of full-sized Handshake and 1-RTT packet).

Are we fine with that? Shouldn't we better change the TP to `max_datagram_size`?

-- 
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/3447#issuecomment-588714349

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 20 Feb 2020 06:13:00 -0800

I've opened #3471 to discuss the issue described in my comment right above.

-- 
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/3447#issuecomment-589065696

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 20 Feb 2020 06:58:38 -0800

Regarding the original issue, I think I prefer something different than the two options being suggested.

3. Do not require any behavior on the client-side. Allow servers process packets (or datagrams) larger than the advertised limit.

As stated in my previous comment, there is a risk of seeing inferior performance when the client uses a large packet size that was advertised by the previous connection which is greater than the new max_packet_size, and if the server accepts 0-RTT. But the fact is that by sending a packet that is larger than 1200 bytes, the client is already taking the risk that 0-RTT packets might get dropped (by the network).

Also, I do not see why endpoints have to be required to drop packets (or datagrams) that is greater than the advertised value.

I think we can simply say that max_packet_size (or max_datagram_size) is an advisory value, much like max_idle_timeout.

-- 
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/3447#issuecomment-589092455

---

From: Nick Banks <[email-masked]>
Date: Thu, 20 Feb 2020 07:03:27 -0800

I like @kazuho's suggestion, and I especially agree with the point about already risking the network dropping the packet if it's more than 1200 bytes.

There's no need to say you must drop the packet if it's bigger. If you ended up being able to receive the packet successfully even though it was more than you advertised, go ahead and process it.

-- 
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/3447#issuecomment-589095058

---

From: martinduke <[email-masked]>
Date: Thu, 20 Feb 2020 14:05:07 -0800

I suppose the only normative change from the existing text would be that clients MAY forget the value from previous connections when sending 0RTT. While I don't have a strong opinion on this, I think I'd prefer to just close this with no action, or at most an editorial change, thus forcing clients to remember the value. Freeing the client is not a lot of value add for protocol churn at this stage.

-- 
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/3447#issuecomment-589362529

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 20 Feb 2020 16:20:39 -0800

> While I don't have a strong opinion on this, I think I'd prefer to just close this with no action, or at most an editorial change, thus forcing clients to remember the value. Freeing the client is not a lot of value add for protocol churn at this stage.

I think the counter argument would be that it does not cause churn, because clients that are willing to remember the value can.

Also, assuming that we agree that "max_packet_size" was in fact "max_udp_payload_size" (as we've been discussing in #3473), I'd point out that applying the "max_udp_payload_size" of the previous connection is going to be pretty complex. A client should not be sending a coalesced datagram that is greater than "max_udp_payload_size" until it learns that peer's maximum for the current connection. Therefore, a client would be having different limits on the packet size depending of if it is generating a coalesced packet.

I am not sure if we should design our protocol based on such a complex (and IMO fragile) design.

-- 
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/3447#issuecomment-589437605

---

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

I don't like @kazuho's proposed change.  The point of this is to express a limitation of the endpoint.  If the endpoint only has X bytes of memory for receiving packets, then it can use this limit.  Absent this, we can't ever hope to have big endpoints talking to little ones.  We will end up with middleboxes (hello CoAP).

If the limit exists at a server and the client ignores it for 0-RTT, then the effect is that 0-RTT doesn't get through.  I would rather just say that client's are expected to remember it and then if they don't they can wear the consequences.  But that can be a protocol violation.

The problem here is that we now have protection for Initial packets and no way to signal that there is a limit.  Our only real protection there is that the limit manifests in much the same way as having a lower MTU because Initial packets don't get through.

This matters especially if clients start remembering or inferring path MTU.  I don't remember us ever expressly allowing this sort of thing, but it seems like a reasonable thing that might happen when probing can be quite costly and wasteful.

-- 
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/3447#issuecomment-589493084

---

From: Kazuho Oku <[email-masked]>
Date: Thu, 20 Feb 2020 21:10:43 -0800

> I don't like @kazuho's proposed change. The point of this is to express a limitation of the endpoint. If the endpoint only has X bytes of memory for receiving packets, then it can use this limit. A…

Yes, I share the view that the sender should adhere to the receiver's advertised limit. But that does not mean that exceeding the limit needs to trigger a protocol violation, or if the receiver should be allowed to trigger that.

I might argue that, in practice, receivers would not trigger protocol violation when it receives a QUIC packet that is larger than the advertised maximum. This is because the receiver has to decrypt the packet that is larger than its limit in order to check that the packet was not spoofed. But is there an incentive to have a buffer that is larger than the advertised maximum just for this purpose? I do not think so. I'd assume that endpoints would simply advertise its buffer size.

I think we just have different view points. One way of viewing this TP is that it is an ordinary TP, and therefore that when 0-RTT is being used, the resumed connection inherits this TP too from the previous connection.

The other way of viewing this TP is that it is an optimization of PMTUD, that lets a receiver advertise the maximum size of a datagram that is capable of processing. PMTUD needs to be applied per each connection (or to be precise per each path), regardless of if 0-RTT is used. If we view the TP this way, it can be considered something that kicks in when the TP is received for every connection.

IMO the latter view is simpler in terms of implementation complexity, and has no downsides.

-- 
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/3447#issuecomment-589501315

---

From: Martin Thomson <[email-masked]>
Date: Sat, 22 Feb 2020 15:01:10 -0800

This is probably right.  The effect of exceeding this limit is most likely that the packet will be dropped.  So it looks like an MTU limitation that exists regardless of the path.

Encouraging clients to remember this is still the right thing to do though.  The alternative is terrible performance, as only some 0-RTT packets - the small ones - end up getting through.

-- 
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/3447#issuecomment-590006670