2026年3月26日(木) 14:07 Willy Tarreau <[email protected]>:

> On Thu, Mar 26, 2026 at 03:19:49PM +1100, Martin Thomson wrote:
> > On Wed, Mar 25, 2026, at 15:34, Kazuho Oku wrote:
> > >  Yes, using short TLS records during startup is important. In fact,
> h2o
> > > has long been doing that for HTTP/2.
> >
> > Definitely.  Long TLS records leads to more latency, because more bytes
> share fate.
> >
> > > I would argue, however, that when a QMux sender emits short TLS
> > > records, it should also use correspondingly short framing units.
> >
> > This is where we start to diverge.  TLS is the only layer at which
> framing
> > forces receivers to wait for bytes.  At the QMux layer, you can receive
> 10
> > bytes of a 1k record.  Those 10 bytes are usable.  Introducing record
> framing
> > *encourages* implementers to be lazy and wait for the whole record, but
> > that's going to make their implementation more vulnerable to performance
> > problems.
>
> I agree, but you and Kazuho are not speaking about the same thing. Your
> (and my) concerns are that we don't needlessly complicate the protocol
> with rules/constraints that are not strictly needed. Kazuho's concern is
> that the sender of an large data frame doesn't stop sending in the middle
> of that data frame, blocking the mux output and preventing any other higher
> priority frame from being sent.
>
> This last point is exactly what H2 already has to deal with, and I would
> say that it's purely implementation-specific. Some implementations might
> very well want to send super large frames that are progressively split into
> TLS recors that are decrypted by the receiver which progressively reads,
> while others might prefer to produce more smaller frames (and possibly
> smaller TLS records) to make sure never to leave the mux in a blocked
> state. In haproxy with h2 for example we always make data frames that
> can fit into the available buffers to make sure never to block any other
> frame. But that's only a choice, as the mux also supports sending only a
> partial frame (e.g. a large headers frame).
>

 Yes, implementations can use different strategies to avoid blocking.

At the same time, I think MT is correct to point out that specifications
guide developers to implement their stacks in specific ways. From that
perspective, the QMux Record approach prioritizes minimizing divergence
from existing QUIC stacks, and then, as a secondary goal, mitigates the
effect of blocking by encouraging alignment between TLS record and QUIC
frame boundaries.

The alternative direction would be to optimize more aggressively against
blocking, even if that means requiring all implementations to diverge more
substantially from QUIC v1 decoding / processing behavior. IMO that would
look like H3 frames that have no size limit and require incremental
processing; see
https://mailarchive.ietf.org/arch/msg/quic/K1vMcAoai0oVUr-r5UU_QBfmrwU/.

At this point, I do not see a particularly attractive middle ground between
these two directions.


> Also in my opinion we shouldn't put too many TLS-based constraints because
> TLS is one way to securely transport qmux and which happens to use records,
> but for example UNIX stream sockets would not have such restrictions. And
> by the way, H2 doesn't require to know the TLS record lengths either.
>

I agree that Unix sockets do not have the TLS property of delivering bytes
that have been read but cannot yet be decrypted. Therefore, blocking
becomes inevitable on Unix sockets, unless QMux receivers implement
incremental processing of STREAM frames. That downside might be negligible
considering the low latency and high bandwidth of Unix sockets.

On the other hand, people have expressed interest in running QMux over
message-oriented substrates such as RDMA or WebSockets. For such
deployments, having a record layer that can be mapped more naturally onto
the underlying substrate could be beneficial.

So I think this is another trade-off, after all.


> Just my two cents,
> Willy
>


-- 
Kazuho Oku

Reply via email to