OPTIM: h3: skip buf realign if no trailer to encode
h3_resp_trailers_send() may be called due to an HTX EOT block present
without preceeding HTX TRAILER block. In this case, no HEADERS frame
will be generated by H3 layer and MUX will emit an empty STREAM frame
with FIN set.
However, before skipping these, some operations are conducted on qcs
buffer to realign it and try to encode the QPACK field section line in a
buffer copy. These operation are thus unneeded if no trailer is
generated. Even worse, the function will fail if there is not enough
space in the buffer for the superfluous QPACK section line.
To improve this situation, this patch adds an early goto statement to
skip most operations in h3_resp_trailers_send() if no HTX trailer block
is found.
This patch is related to github issue #2006.
This should be backported up to 2.7.
diff --git a/src/h3.c b/src/h3.c
index cbb7540..14637e5 100644
--- a/src/h3.c
+++ b/src/h3.c
@@ -1377,6 +1377,13 @@
}
}
+ if (!hdr) {
+ /* No headers encoded here so no need to generate a H3 HEADERS
+ * frame. Mux will send an empty QUIC STREAM frame with FIN.
+ */
+ TRACE_DATA("skipping trailer", H3_EV_TX_HDR, qcs->qcc->conn, qcs);
+ goto end;
+ }
list[hdr].n = ist("");
res = mux_get_buf(qcs);
@@ -1420,24 +1427,24 @@
}
}
- /* Now that all headers are encoded, we are certain that res buffer is
- * big enough.
- */
-
/* Check that at least one header was encoded in buffer. */
- if (b_tail(&headers_buf) != tail) {
- b_putchr(res, 0x01); /* h3 HEADERS frame type */
- if (!b_quic_enc_int(res, b_data(&headers_buf), 8))
- ABORT_NOW();
- b_add(res, b_data(&headers_buf));
- }
- else {
+ if (b_tail(&headers_buf) == tail) {
/* No headers encoded here so no need to generate a H3 HEADERS
* frame. Mux will send an empty QUIC STREAM frame with FIN.
*/
TRACE_DATA("skipping trailer", H3_EV_TX_HDR, qcs->qcc->conn, qcs);
+ goto end;
}
+ /* Now that all headers are encoded, we are certain that res buffer is
+ * big enough.
+ */
+ b_putchr(res, 0x01); /* h3 HEADERS frame type */
+ if (!b_quic_enc_int(res, b_data(&headers_buf), 8))
+ ABORT_NOW();
+ b_add(res, b_data(&headers_buf));
+
+ end:
ret = 0;
blk = htx_get_head_blk(htx);
while (blk) {