MINOR: quic: Send PING frames when probing Initial packet number space
In very very rare cases, it is possible the Initial packet number space
must be probed even if it there is no more in flight CRYPTO frames.
In such cases, a PING frame is sent into an Initial packet. As this
packet is ack-eliciting, it must be padded by the server. qc_do_build_pkt()
is modified to do so.
Take the opportunity of this patch to modify the trace for TX frames to
easily distinguished them from other frame relative traces.
Must be backported to 2.7.
diff --git a/src/quic_conn.c b/src/quic_conn.c
index 81ad537..60af8b8 100644
--- a/src/quic_conn.c
+++ b/src/quic_conn.c
@@ -3429,7 +3429,7 @@
/* Pad this Initial packet if there is no ack-eliciting frames to send from
* the next packet number space.
*/
- if (LIST_ISEMPTY(next_tel_frms))
+ if (!next_tel_frms || LIST_ISEMPTY(next_tel_frms))
padding = 1;
}
@@ -4539,6 +4539,14 @@
LIST_SPLICE(&iqel->pktns->tx.frms, &ifrms);
LIST_SPLICE(&hqel->pktns->tx.frms, &hfrms);
}
+ else {
+ if (!(qc->flags & QUIC_FL_CONN_ANTI_AMPLIFICATION_REACHED)) {
+ iqel->pktns->tx.pto_probe = 1;
+ if (!qc_send_hdshk_pkts(qc, 0, QUIC_TLS_ENC_LEVEL_INITIAL, &ifrms,
+ QUIC_TLS_ENC_LEVEL_NONE, NULL))
+ goto leave;
+ }
+ }
}
TRACE_STATE("no more need to probe Initial packet number space",
QUIC_EV_CONN_TXPKT, qc);
@@ -7456,6 +7464,9 @@
len_sz = quic_int_getsize(len);
/* Add this packet size to <dglen> */
dglen += head_len + len_sz + len;
+ /* Note that <padding> is true only when building an Handshake packet
+ * coalesced to an Initial packet.
+ */
if (padding && dglen < QUIC_INITIAL_PACKET_MINLEN) {
/* This is a maximum padding size */
padding_len = QUIC_INITIAL_PACKET_MINLEN - dglen;
@@ -7475,10 +7486,22 @@
/* If we cannot send a frame, we send a PING frame. */
add_ping_frm = 1;
len += 1;
+ dglen += 1;
+ /* Note that only we are in the case where this Initial packet
+ * is not coalesced to an Handshake packet. We must directly
+ * pad the datragram.
+ */
+ if (pkt->type == QUIC_PACKET_TYPE_INITIAL && dglen < QUIC_INITIAL_PACKET_MINLEN) {
+ padding_len = QUIC_INITIAL_PACKET_MINLEN - dglen;
+ padding_len -= quic_int_getsize(len + padding_len) - len_sz;
+ len += padding_len;
+ }
+ }
+ else {
+ /* If there is no frame at all to follow, add at least a PADDING frame. */
+ if (!ack_frm_len && !cc)
+ len += padding_len = QUIC_PACKET_PN_MAXLEN - *pn_len;
}
- /* If there is no frame at all to follow, add at least a PADDING frame. */
- if (!ack_frm_len && !cc)
- len += padding_len = QUIC_PACKET_PN_MAXLEN - *pn_len;
}
if (pkt->type != QUIC_PACKET_TYPE_SHORT && !quic_enc_int(&pos, end, len))
diff --git a/src/quic_frame.c b/src/quic_frame.c
index 530a640..2528dec 100644
--- a/src/quic_frame.c
+++ b/src/quic_frame.c
@@ -1155,7 +1155,7 @@
goto leave;
}
- TRACE_PROTO("frame", QUIC_EV_CONN_BFRM, qc, frm);
+ TRACE_PROTO("TX frame", QUIC_EV_CONN_BFRM, qc, frm);
*pos++ = frm->type;
if (!quic_frame_builders[frm->type].func(&pos, end, frm, qc)) {
TRACE_DEVEL("frame building error", QUIC_EV_CONN_BFRM, qc, frm);