Subject: [QUIC] Multiple frames of the same type per packet?

From: "Eggert, Lars" <[email-masked]>
Date: Fri, 21 Oct 2016 12:04:19 +0000

Hi,

Section 10 says:

> 10.  Frame Types and Formats
> 
>    A single Regular Packet MAY contain multiple frames and multiple
>    frame types.

However, it remains unclear if a regular packet is permitted to contain multiple frames of the same type. I guess this should be permitted for STREAM frames. But is there any reason to permit this for any of the other frame types?

Thanks,
Lars

---

From: Christian Huitema <[email-masked]>
Date: Fri, 21 Oct 2016 06:10:13 -0700

There are good reasons to have multiple stream and stream control frames. Not much point in having multiple ACK or similar frames, but we have to weight the cost. Forbidding it means more code. The natural implementation is to process a queue of frames as they arrive in one or multiple packets. To forbid it you need to add code, and that can be a source of bugs.

Now, there is another issue. Frames can be received and processed out of order. We need to analyze for each frame what the consequences are.

-- Christian Huitema 

> On Oct 21, 2016, at 5:04 AM, Eggert, Lars <[email-masked]> wrote:
> 
> Hi,
> 
> Section 10 says:
> 
> _______________________________________________
> QUIC mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/quic

---

From: Robbie Shade <[email-masked]>
Date: Fri, 21 Oct 2016 09:13:56 -0400

I think for any of the stream-specific frame types it makes sense to allow
multiples in one packet. For example if an endpoint wants to reset N
streams, they should be able to send a single packet with as many
RST_STREAM frames packed in as possible, rather than sending N packets each
with a single frame. The same argument applies to WINDOW_UPDATE, BLOCKED,
and of course STREAM frames.

On Fri, Oct 21, 2016 at 8:04 AM, Eggert, Lars <[email-masked]> wrote:

> However, it remains unclear if a regular packet is permitted to contain
> multiple frames of the same type. I guess this should be permitted for
> STREAM frames. But is there any reason to permit this for any of the other
> frame types?
>
> Thanks,
> Lars

---

From: Christian Huitema <[email-masked]>
Date: Fri, 21 Oct 2016 06:10:13 -0700

-- Christian Huitema

---

From: Ian Swett <[email-masked]>
Date: Fri, 21 Oct 2016 09:44:43 -0400

Multiple reset stream, window update, or blocked frames would be valid as
well.  For other frame types, I believe it would not.

It's likely worth clarifying this?

---

From: Joerg Ott <[email-masked]>
Date: Fri, 21 Oct 2016 15:52:36 +0200

Christian's point that forbidding certain combinations requires checking
and appropriate reaction and thus needs code and increases complexity is
well taken.

If multiple frames of the same type pertaining, e.g., to the same stream
or connection, are included, it may make sense to clearly specify that
must be handled in the order they appear in the packet and that state
updates are performed on each such frame so that the next one only acts
upon the outcome.  This would lead to frame being treated the same no
matter if they are in the same packet or not.  (But I am not sure if
this works for all the QUIC protocol machinery.)

Jörg

On 21.10.16 15:44, Ian Swett wrote:
> Multiple reset stream, window update, or blocked frames would be valid
> as well.  For other frame types, I believe it would not.
>
> On Fri, Oct 21, 2016 at 8:04 AM, Eggert, Lars <[email-masked]
> <mailto:[email-masked]>> wrote:
>
>     Hi,
>
>     Section 10 says:
>
>     However, it remains unclear if a regular packet is permitted to
>     contain multiple frames of the same type. I guess this should be
>     permitted for STREAM frames. But is there any reason to permit this
>     for any of the other frame types?
>
>     Thanks,
>     Lars
>     [email-masked] <mailto:[email-masked]>
>     <https://www.ietf.org/mailman/listinfo/quic>
>
>
>
>

---

From: Martin Thomson <[email-masked]>
Date: Sat, 22 Oct 2016 19:53:14 +1100

> and appropriate reaction and thus needs code and increases complexity is

You don't have to insist on the receiver enforcing this, all you have
to do is permit them to.  Of course, the most is gained when every
implementation checks and reports it (by killing the connection or
something equally visible, of course), then you find that mistakes are
quickly identified.

I get Christian's point, but the amount of extra code is worth it.
Then you don't end up with systemic tolerance for bad implementations.

---

From: "Christian Huitema" <[email-masked]>
Date: Sat, 22 Oct 2016 11:06:11 -0700

> something equally visible, of course), then you find that mistakes are

Yes. Crowd immunity and all that. 

> Then you don't end up with systemic tolerance for bad implementations.

I would be OK with something like "must not include the same frame type
related to the same stream more than once per packet, may drop connections
if encountering a packet that violates that rule." The point is that
compliance is easy, it is quite natural to only process a particular stream
once per packet, but enforcement is somewhat onerous. I would not want to
end up with some kind of compliance test in which the tester sends malformed
packets and flags the implementation as non-conforming because it did not
implement the verification code.

-- Christian Huitema

---

From: Martin Thomson <[email-masked]>
Date: Mon, 24 Oct 2016 10:55:40 +1100

> implement the verification code.

Right, this is also my preference.  Having the escape valve is
particularly relevant in cases where your implementation is
constrained in some way.

---

From: Jana Iyengar <[email-masked]>
Date: Mon, 24 Oct 2016 20:08:37 -0700

> particularly relevant in cases where your implementation is

Two things are not clear to me:
1. Why are these checks necessary? I don't think they're necessary for
correctness.
2. What's the incentive for a receiver to implement these checks? If it's
work, and if _not implementing_ these checks allows for interop with more
senders, why would a receiver implement these checks?

As Christian said earlier, a natural sender would queue frames and
packetize when deemed necessary. An inefficient sender may pack, for
example, multiple stream frames belonging to the same stream in the same
packet, but that's inefficient, not incorrect. A recommendation here can
point to good practice. It seems reasonable to recommend that a sender
SHOULD "not include the same frame type related to the same stream more
than once per packet." Saying that a receiver MAY drop a connection that
violates this agreement seems unnecessary.

---

From: "Eggert, Lars" <[email-masked]>
Date: Tue, 25 Oct 2016 03:30:06 +0000

On 2016-10-25, at 5:08, Jana Iyengar <[email-masked]> wrote:
> 1. Why are these checks necessary? I don't think they're necessary for correctness.
> 2. What's the incentive for a receiver to implement these checks? If it's work, and if _not implementing_ these checks allows for interop with more senders, why would a receiver implement these checks?
> 
> As Christian said earlier, a natural sender would queue frames and packetize when deemed necessary. An inefficient sender may pack, for example, multiple stream frames belonging to the same stream in the same packet, but that's inefficient, not incorrect. A recommendation here can point to good practice. It seems reasonable to recommend that a sender SHOULD "not include the same frame type related to the same stream more than once per packet." Saying that a receiver MAY drop a connection that violates this agreement seems unnecessary.

That makes sense, and an uppercase SHOULD may not even be needed, i.e., the explanation can be phrased in terms of the inefficiency you describe above.

(I raised the question, because when I read the text, I was wondering if my code should throw a warning when it received such packets.)

Lars

---

From: Jana Iyengar <[email-masked]>
Date: Mon, 24 Oct 2016 21:55:07 -0700

On Mon, Oct 24, 2016 at 8:30 PM, Eggert, Lars <[email-masked]> wrote:

> > 2. What's the incentive for a receiver to implement these checks? If
> it's work, and if _not implementing_ these checks allows for interop with
> more senders, why would a receiver implement these checks?
> >
> That makes sense, and an uppercase SHOULD may not even be needed, i.e.,
> the explanation can be phrased in terms of the inefficiency you describe
> above.
>

That seems reasonable to me.

- jana

> (I raised the question, because when I read the text, I was wondering if
> my code should throw a warning when it received such packets.)
>
> Lars