<aside> 💡 Series:
HoL Blocking and Priority Inversion in QUIC
HoL Blocking Allows Attacks in QUIC
HoL Blocking and the Deadlock Hazard in QUIC
Relates: Head-of-Line Blocking in QUIC and HTTP/3: The Details
</aside>
SMITH: Doctor, it hurts when I do this.
DALE: Don’t do that.
To achieve the best header compression performance, it is tempting to have the compression protocol allow potential (HoLB). The idea is that HoLB will not occur most of the time, while the compression gain is significant. The first article of this series exposes priority inversion caused by HoLB and challenges the assertion that HoLB is rare. The second problem is that HoLB is a potential attack vector, wherein the decoder is tricked into using a lot of memory. One way to prevent such attack is to not read from the stream until the decoder can process the stream immediately. This approach creates a deadlock hazard. This problem is examined in this article.
If a header block B depends on an entry inserted by header block A, we say that B depends on A. Together, they are dependent header blocks.
Writing dependent header blocks to stream out of order introduces the risk of a deadlock. There are two types of a deadlock.
When dependent header blocks are written out of order to the same stream, the first header block cannot be parsed because it depends on the block that follows it.
This type of deadlock happens when the out-of-order header block prevents the receiver from reading stream data that follows the header block. What makes it different from the regular HoLB case is that the sender cannot put the resolving header block onto the stream due to the limits imposed by the QUIC connection flow control.
One way a multi-stream deadlock can occur is when a header block must be resent after a stream reset. By the time the sender figures out that it needs to resend a header block, it may have filled all existing streams to the brim — which the receiver cannot drain — and is not allowed to stream more data.
One potential solution is always to leave some room in the connection flow control window. That is, leave at least the number of bytes required to resend all unacknowledged header blocks.
There are downsides to this approach: